Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Unique index on array element's property

Tags:

mongodb

I have a structure similar to this:

class Cat {   int id;   List<Kitten> kittens; }  class Kitten {   int id; } 

I'd like to prevent users from creating a cat with more than one kitten with the same id. I've tried creating an index as follows:

db.Cats.ensureIndex({'id': 1, 'kittens.id': 1}, {unique:true}) 

But when I attempt to insert a badly-formatted cat, Mongo accepts it.

Am I missing something? can this even be done?

like image 770
Electric Monk Avatar asked Jul 19 '11 07:07

Electric Monk


People also ask

Can we create index on array in MongoDB?

Yes, you can and it works: To index a field that holds an array value, MongoDB creates an index key for each element in the array. These multikey indexes support efficient queries against array fields.

How do you make an array unique in MongoDB?

To get unique values within two arrays in a document, use a $setUnion in aggregate(). The $setUnion takes two or more arrays and returns an array containing the elements that appear in any input array.

Are MongoDB indexes unique?

By default, MongoDB creates a unique index on the _id field during the creation of a collection.

Can you create an index on an array field in MongoDB If yes what happens in this case?

MongoDB automatically creates a multikey index if any indexed field is an array; you do not need to explicitly specify the multikey type.


2 Answers

As far as I know, unique indexes only enforce uniqueness across different documents, so this would throw a duplicate key error:

db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } ) db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } ) 

But this is allowed:

db.cats.insert( { id: 123, kittens: [ { id: 456 }, { id: 456 } ] } ) 

I'm not sure if there's any way enforce the constraint you need at the Mongo level, maybe it's something you could check in the application logic when you insert of update?

like image 147
Chris Fulstow Avatar answered Oct 05 '22 11:10

Chris Fulstow


Ensuring uniqueness of the individual values in an array field

In addition to the example above, there is a function in MongoDB to ensure that when you are adding a new object/value to an array field, that it will only perform the update if the value/object doesn't already exist.

So if you have a document that looks like this:

{ _id: 123, kittens: [456] } 

This would be allowed:

db.cats.update({_id:123}, {$push: {kittens:456}}) 

resulting in

{ _id: 123, kittens: [456, 456] } 

however using the $addToSet function (as opposed to $push) would check if the value already exists before adding it. So, starting with:

{ _id: 123, kittens: [456] } 

then executing:

db.cats.update({_id:123}, {$addToSet: {kittens:456}}) 

Would not have any effect.

So, long story short, unique constraints don't validate uniqueness within the value items of an array field, just that two documents can't have identical values in the indexed fields.

like image 35
doublehelix Avatar answered Oct 05 '22 11:10

doublehelix