qq: unique index ?

42 views
Skip to first unread message

Ted Chyn

unread,
Oct 15, 2014, 10:14:34 PM10/15/14
to mongod...@googlegroups.com



1.  test1 collection has field a contain array notice duplicate value of 1 in the array. I can create a unique index on field a
    see db.test1.getIndex()
db.test1.find()
{ "_id" : 2, "a" : [ 1, 2, 3, 1 ] }
test@-Mongo-> db.test1.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.test1"
},
{
"v" : 1,
"unique" : true,
"key" : {
"a" : 1
},
"name" : "a_1",
"ns" : "test.test1"
}
]
2. when I tried to add another doc with a:1  ### got duplicate value
test@-Mongo-> db.test1.insert({a:1});
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.test1.$a_1  dup key: { : 1.0 }"
}
3. for array index mongodb put every entry in array in a index like unwind operation in aggregate command. so there should be 4
   entries in the unque index
    1       2   3  1  and one is duplicate but unique=true does not exclude this entry as duplicate why ?
   
 4. as soon as I tried to add another entry with duplicate value I got duplicate error. How does this behavior reconcile to 3. above ?

thanks in advance
ted  

Stephen Steneker

unread,
Oct 15, 2014, 10:46:33 PM10/15/14
to mongod...@googlegroups.com
Hi Ted,

As at MongoDB 2.6, the unique index constraint applies at the document level rather than the array or embedded document level. There is an open server issue discussing this behaviour if you want to watch/upvote it: SERVER-1068.

For example, you can continue to push duplicate values to an array in the same document:

>  db.test1.ensureIndex({a:1},{unique:true})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}

>   db.test1.insert({ "_id" : 2, "a" : [ 1, 2, 3, 1 ] })
WriteResult({ "nInserted" : 1 })

>   db.test1.update({_id:2}, { $push: { a : 1 }})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>   db.test1.update({_id:2}, { $push: { a : 1 }})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })


If you want to ensure unique values in array, you can instead push to the array using the $addToSet operator:

> db.test1.update({_id:2}, { $addToSet: { a : 1 }})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

Note that $addToSet doesn't remove any existing duplicates, it just avoids adding any new duplicate entries to that array.

Regards,
Stephen

Ted Chyn

unread,
Oct 16, 2014, 10:06:40 AM10/16/14
to mongod...@googlegroups.com
stephen, thanks for the insight.  is this true that mongodb unwind the array and store the denormalized array in a binary treeindex ?  so array [1,2,3,1] unwind into 4 entries in the binary index ?  

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/lysCzKS9Jgc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/ce83c6db-8f8c-42b2-b264-c71239b43c49%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Asya Kamsky

unread,
Oct 22, 2014, 9:44:49 PM10/22/14
to mongodb-user
> so array [1,2,3,1] unwind into 4 entries in the binary index ?

Not really. There are only three indexable values there, 1, 2 and 3.

So value 1 does not "appear" twice in the index, it's in the index
once (one entry for each value) and it points only at a single
document (the one it appears in - even if it's more than once).

Asya
> You received this message because you are subscribed to the Google Groups
> "mongodb-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mongodb-user...@googlegroups.com.
> To post to this group, send email to mongod...@googlegroups.com.
> Visit this group at http://groups.google.com/group/mongodb-user.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/mongodb-user/CAKLPb0pW7YJdy-dLfdQUdDtnJe%3DY%2BAOXooBFoq98NSfrMDn_XQ%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages