Reputation: 1207
Say we have a collection of documents similar to this:
{
foo: "Bar",
foos: [1, 2, 3]
}
I would like to define a unique index such that no document identical to this one can be inserted into the database.
db.stuffs.ensureIndex({ foos: 1 }, { unique: true })
Seems to block any document containing a foos
array with any intersection, eg. if the document above was already in the database, then
{
foo: "Bar",
foos: [ 1 ]
}
Would also be blocked.
> db.stuffs.ensureIndex({ foos: 1 }, { unique: true })
> db.stuffs.insert({ foo: "Bar", foos: [ 1, 2, 3 ]})
> db.stuffs.insert({ foo: "Bar", foos: [ 1 ]})
E11000 duplicate key error index: test.stuffs.$foos_1 dup key: { : 1.0 }
I would like to be able to make insertions of [ 1, 2 ], [ 2, 1 ], [ 1, 3 ], etc. but not two [ 1, 2 ]
Upvotes: 3
Views: 2314
Reputation: 2099
If the array that you want to index is of constant size, you can create a unique multikey index like this:
collection.createIndex({"coordinate.0": 1, "coordinate.1": 1}, {unique: true})
coordinate
is an array of size 2.
When I try to insert a duplicate coordinate, it returns an error as expected.
Upvotes: 0
Reputation: 86
Please refer to this question. Explains why Unique Index won't work in this case.
To index a field that holds an array value, MongoDB creates an index key for each element in the array.
Upvotes: 0
Reputation: 790
The array index will not meet your requirement. But I think you can switch to the other format to store your data.
If there is no need to use the feature of array (such as $addToSet, $push op), you can simply hash/map your data to another format. e.g.: [1,2,3] to the string "1,2,3".
While I assume that you want to remain the array operations in order to make some updates. Then you can try the subdocument below:
db.stuffs.ensureIndex({ foos: 1 }, { unique: true }) // build the index for the sub doc
db.stuffs.insert({ foo: "Bar", foos: {k:[ 1, 2, 3 ]}})
db.stuffs.insert({ foo: "Bar", foos: {k:[ 1 ]}})
db.stuffs.update({ "_id" : ObjectId("54081f544ea4d4e96bffd9ad")}, {$push:{"foos.k": 2}})
db.stuffs.insert({ foo: "Bar", foos: {k:[1, 2]}})
E11000 duplicate key error index: test.stuffs.$foos_1 dup key: { : { k: [ 1.0, 2.0 ] } }
Upvotes: 1