Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB setOnInsert and push if already existent

I would like to add a document if it does not exist and else add an element to one of it's sub-documents.

db.test.update(
  {
    name : 'Peter'
  },
  $setOnInsert : { 
      name : 'Peter', 
      visits: { 'en' : ['today'], 'us' : [] }
  },
  $push : {
      visits.en : 'today'
  },
  { upsert : true }
)

If Peter exists, add an element to its visists.en or visists.us arrays. Else, create a document for Peter. This document should have the format for visits which should contain the current element ('today').

My issue is that I have "have conflicting mods in update". I.e. (afaik), I cannot write to two things in one query. Yet how can I solve this dilemma?

like image 615
Marius Avatar asked Feb 15 '14 23:02

Marius


2 Answers

You could implement it without $setOnInsert operator.

db.test.update(
  {
    name : 'Peter'
  },
  {
    $push : {
      "visits.en" : 'today'
    }
  },
  { upsert : true }
)

If Peter exists, element 'today' will be added to its visits.en array. Else, will be created a document for Peter, with visits object, that will be contain array en with 'today' element.
And I think, that error occured because of you using same property (visits) in two operations ($setOnInsert and $push).

like image 127
Ivan.Srb Avatar answered Oct 21 '22 14:10

Ivan.Srb


You can still use $setOnInsert but when $setOnInsert and $push doesn't updates in the same fields as mentioned before.

N.b: We use $addToSet if you don't want a duplicated values in your Array

db.test.update(
    {
      name : 'Peter'
    }, 
     {
      $setOnInsert: {name : 'Peter'},
      $addToSet: {"visits.en": 'today'} // or $push
     },
     {upsert: true})
like image 43
Farouk El kholy Avatar answered Oct 21 '22 13:10

Farouk El kholy