dave
dave

Reputation: 1207

Unique Index on Array in MongoDB

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

Answers (3)

MakotoE
MakotoE

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

Abhishek Deora
Abhishek Deora

Reputation: 86

Please refer to this question. Explains why Unique Index won't work in this case.

Unique index in MongoDB

To index a field that holds an array value, MongoDB creates an index key for each element in the array.

Upvotes: 0

Mark_H
Mark_H

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

Related Questions