Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you specify a key for $addToSet in Mongo?

I have a document:

{ 'profile_set' :
  [
    { 'name' : 'nick', 'options' : 0 },
    { 'name' : 'joe',  'options' : 2 },
    { 'name' : 'burt', 'options' : 1 }
  ] 
}

and would like to add a new document to the profile_set set if the name doesn't already exist (regardless of the option).

So in this example if I tried to add:

{'name' : 'matt', 'options' : 0}

it should add it, but adding

{'name' : 'nick', 'options' : 2}

should do nothing because a document already exists with name nick even though the option is different.

Mongo seems to match against the whole element and I end up with to check if it's the same and I end up with

profile_set containing [{'name' : 'nick', 'options' : 0}, {'name' : 'nick', 'options' : 2}]

Is there a way to do this with $addToSet or do I have to push another command?

like image 621
nickponline Avatar asked Jan 25 '13 18:01

nickponline


People also ask

How do you use $addToSet?

The $addToSet operator adds a value to an array unless the value is already present, in which case $addToSet does nothing to that array. The $addToSet operator has the form: { $addToSet: { <field1>: <value1>, ... } } To specify a <field> in an embedded document or in an array, use dot notation.

How do I add a value to an array in MongoDB?

If the value is an array, $push appends the whole array as a single element. To add each element of the value separately, use the $each modifier with $push . For an example, see Append a Value to Arrays in Multiple Documents. For a list of modifiers available for $push , see Modifiers.

How do I remove an element from an array in MongoDB?

To remove an element, update, and use $pull in MongoDB. The $pull operator removes from an existing array all instances of a value or values that match a specified condition.

How do I update an array in MongoDB?

Learn how to update array fields in documents in MongoDB collections. You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.


2 Answers

You can qualify your 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'.

like image 104
JohnnyHK Avatar answered Oct 17 '22 04:10

JohnnyHK


As of MongoDB 4.2 there is a way to do this using aggregation expressions in update.

For your example case, you would do this:

newSubDocs = [ {'name' : 'matt', 'options' : 0}, {'name' : 'nick', 'options' : 2} ];
db.coll.update( { _id:1 },
[ 
   {$set:  { profile_set:  {$concatArrays: [ 
      "$profile_set",  
      {$filter: {
             input:newSubDocs, 
             cond: {$not: {$in: [ "$$this.name", "$profile_set.name" ]}} 
      }}
   ]}}}
])
like image 29
Asya Kamsky Avatar answered Oct 17 '22 04:10

Asya Kamsky