I have a document:
{ 'profile_set' :
[
{ 'name' : 'nick', 'options' : 0 },
{ 'name' : 'joe', 'options' : 2 },
{ 'name' : 'burt', 'options' : 1 }
]
}
If I want to add new object to the profile_set
only if the name
of the object isn't already taken, regardless of the options
, I can qualify my update
with a query object that prevents the update if the name
is already present in profile_set
. In the shell:
db.coll.update(
{_id: id, 'profile_set.name': {$ne: 'nick'}},
{$push: {profile_set: {'name': 'nick', 'options': 2}}})
So this will only perform the $push
for a doc with a matching _id
and where there isn't a profile_set
element where name
is 'nick'
.
Question But if I later need to change Nick's name (and maybe his options too...), that is change an existing array object, not add a new one. Is there a way to do that in one atomic update operation that still honor the unique constraint of name
?
push() adds item(s) to the end of an array and changes the original array. unshift() adds an item(s) to the beginning of an array and changes the original array. splice() changes an array, by adding, removing and inserting elements. slice() copies a given part of an array and returns that copied part as a new array.
To change the value of all elements in an array:Use the forEach() method to iterate over the array. The method takes a function that gets invoked with the array element, its index and the array itself. Use the index of the current iteration to change the corresponding array element.
There are two conditions, I think:
var newName = "somename";
var oldName = "nick";
var newOption = 3;
// if not change the name
db.coll.update({
_id : id,
'profile_set.name' : oldName
}, {
$set : {
"profile_set.$.options" : newOption
}
});
// if change the name
db.coll.update({
_id : id,
$and : [ {
'profile_set.name' : {
$ne : newName
}
}, {
'profile_set.name' : oldName
} ]
}, {
$set : {
"profile_set.$.name" : newName,
"profile_set.$.options" : newOption
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With