MongoDB: Unique index on array element's property
up vote
19
down vote
favorite
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?
mongodb
add a comment |
up vote
19
down vote
favorite
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?
mongodb
1
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19
add a comment |
up vote
19
down vote
favorite
up vote
19
down vote
favorite
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?
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?
mongodb
mongodb
asked Jul 19 '11 at 7:48
Electric Monk
1,32011633
1,32011633
1
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19
add a comment |
1
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19
1
1
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19
add a comment |
3 Answers
3
active
oldest
votes
up vote
27
down vote
accepted
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?
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
add a comment |
up vote
23
down vote
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.
add a comment |
up vote
3
down vote
There is an equivalent of insert with uniquness in array attribute. The following command essentially does insert while ensuring the uniqueness of kittens (upsert creates it for you if the object with 123 doesn't already exist).
db.cats.update(
{ id: 123 },
{ $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},
{ upsert: true}
)
The resulting value of the object will be
{
"id": 123,
"kittens": [456],
"otherfields": "extraval",
"field2": "value2"
}
The important properties are:$addToSet
andupsert
. The$set
property is unrelated to the OP.
– Michael Cole
May 23 '17 at 17:23
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
27
down vote
accepted
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?
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
add a comment |
up vote
27
down vote
accepted
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?
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
add a comment |
up vote
27
down vote
accepted
up vote
27
down vote
accepted
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?
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?
answered Jul 19 '11 at 8:18
Chris Fulstow
30.7k77499
30.7k77499
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
add a comment |
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
2
2
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
Unfortunately it seems like you're right - I'll have to enforce this in code. Oh well.
– Electric Monk
Jul 19 '11 at 22:36
7
7
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
So sad! :(. There should be an option to ensure uniqueness in document arrays.
– Juzer Ali
Aug 3 '12 at 19:06
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
What you can do is write validation hooks when saving in the array to ensure that it is unique
– Ouwen Huang
Nov 23 '14 at 7:53
add a comment |
up vote
23
down vote
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.
add a comment |
up vote
23
down vote
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.
add a comment |
up vote
23
down vote
up vote
23
down vote
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.
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.
answered Nov 17 '13 at 5:14
doublehelix
1,3541212
1,3541212
add a comment |
add a comment |
up vote
3
down vote
There is an equivalent of insert with uniquness in array attribute. The following command essentially does insert while ensuring the uniqueness of kittens (upsert creates it for you if the object with 123 doesn't already exist).
db.cats.update(
{ id: 123 },
{ $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},
{ upsert: true}
)
The resulting value of the object will be
{
"id": 123,
"kittens": [456],
"otherfields": "extraval",
"field2": "value2"
}
The important properties are:$addToSet
andupsert
. The$set
property is unrelated to the OP.
– Michael Cole
May 23 '17 at 17:23
add a comment |
up vote
3
down vote
There is an equivalent of insert with uniquness in array attribute. The following command essentially does insert while ensuring the uniqueness of kittens (upsert creates it for you if the object with 123 doesn't already exist).
db.cats.update(
{ id: 123 },
{ $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},
{ upsert: true}
)
The resulting value of the object will be
{
"id": 123,
"kittens": [456],
"otherfields": "extraval",
"field2": "value2"
}
The important properties are:$addToSet
andupsert
. The$set
property is unrelated to the OP.
– Michael Cole
May 23 '17 at 17:23
add a comment |
up vote
3
down vote
up vote
3
down vote
There is an equivalent of insert with uniquness in array attribute. The following command essentially does insert while ensuring the uniqueness of kittens (upsert creates it for you if the object with 123 doesn't already exist).
db.cats.update(
{ id: 123 },
{ $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},
{ upsert: true}
)
The resulting value of the object will be
{
"id": 123,
"kittens": [456],
"otherfields": "extraval",
"field2": "value2"
}
There is an equivalent of insert with uniquness in array attribute. The following command essentially does insert while ensuring the uniqueness of kittens (upsert creates it for you if the object with 123 doesn't already exist).
db.cats.update(
{ id: 123 },
{ $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}},
{ upsert: true}
)
The resulting value of the object will be
{
"id": 123,
"kittens": [456],
"otherfields": "extraval",
"field2": "value2"
}
answered Nov 17 '16 at 6:18
timchunght
17413
17413
The important properties are:$addToSet
andupsert
. The$set
property is unrelated to the OP.
– Michael Cole
May 23 '17 at 17:23
add a comment |
The important properties are:$addToSet
andupsert
. The$set
property is unrelated to the OP.
– Michael Cole
May 23 '17 at 17:23
The important properties are:
$addToSet
and upsert
. The $set
property is unrelated to the OP.– Michael Cole
May 23 '17 at 17:23
The important properties are:
$addToSet
and upsert
. The $set
property is unrelated to the OP.– Michael Cole
May 23 '17 at 17:23
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f6743849%2fmongodb-unique-index-on-array-elements-property%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
See stackoverflow.com/questions/4435637/…
– pingw33n
Jul 19 '11 at 8:19