2

I have a document:

{ _id: ObjectId("5af06ec792e0fd001f86661d"), 
 'company': 'ABC', 
 '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 OR if it exists then update the existing one.

So in this example if I tried to add:

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

it should add it, but adding

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

should do update the one with name nick because that object already exists with name nick and it will update it other fields value to the new one.

db.coll.update(
    {_id: id, 'profile_set.name': {$ne: 'nick'}}, 
    {$push: {profile_set: {'name': 'nick', 'options': 8}}})

this above command will only add it if it doesn't exist. How can i modify it so that if it exists, the update it with the new values?

update:

I want to find and update as above any document that has 'company': 'ABC'.

4
  • Use .bulkWrite() and issue both operations, being attempt to match and $set the index and $push like you are where it does not exist. Commented May 10, 2018 at 22:16
  • @NeilLunn could you give a full example for this one? Commented May 10, 2018 at 22:17
  • Was searching for a previous answer on this, but to no avail even though I'm sure I've added one before. Oh well, out of close votes right now anyway. Commented May 10, 2018 at 22:19
  • @NeilLunn in fact, i want to do the same operation to any document matching a condition. i updated the question. Commented May 10, 2018 at 22:21

1 Answer 1

4

What you want is bulkWrite() where you issue both operations to $push where not there and $set the "matched" array element in the same server request:

db.coll.bulkWrite([
  { "updateMany": {
    "filter": { company: "ABC", "profile_set.name": "nick" },
    "update": {
      "$set": { "profile_set.$.options": 8 }
    }
  }},
  { "updateMany": {
    "filter": { "company": "ABC", "profile_set.name": { "$ne": "nick"} },
    "update": {
       "$push": { 
         "profile_set": { "name": "nick", "options": 8 }
       }
    }
  }}
])

And under bulkWrite() the variant operation is "updateMany" which is effectively the same as the "multi": true option or the updateMany() method, except we are issuing in "batch".

Sign up to request clarification or add additional context in comments.

2 Comments

ok the first operation adds if not exists, but the second one is not updating the previously added one. is that intended? because i want to update the existing one if exists.
@jacky I doesn't really matter. You can switch them around, and in fact I probably should. MongoDB doesn't actually "modify" anything it finds as the same value anyway. It just matches then does not do anything. I'll change the order in the answer, but as stated, it really does not make that big a difference in the wider scheme.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.