How do I upsert a MongoDB document only in certain circumstances? -


i'm trying update user-document in mongodb collection. if user doesn't exist should created, if exist should updated given query parses checks.

this first tried:

var ts = new date('2015-01-01t00:00:00.000z'); var query = { name: 'bob', updatedat: { $lt: ts } }; var update = { $set: { age: 42, updatedat: ts }, $inc: { updates: 1 } }; db.users.update(query, update, { upsert: true }); 

the problem solution try create user twice if updatedat property less given ts date.

how can make sure it's created if name part of query doesn't match documents, don't if updatedat part doesn't?

basically:

  • the user not exists, create current time "last update time". done using simple upset , $setoninsert;
  • the user exists and need updated. simple update.

simply said, need 2 update statements. but, may wrap them in same update command:

db.runcommand({   update: 'users',   updates: [     { q: { name: 'bob' },       u: { $setoninsert: { updatedat: now, updates: 0 }},       upsert: true },     { q: { name: 'bob', updatedat: { $lt: } },       u: { $set: { updatedat: }, $inc: { updates: 1 } },       upsert: false },   ] }) 

producing on first run (empty collection):

> var = new date() > db.runcommand({   update: 'users',   updates: [     { q: { name: 'bob' },       u: { $setoninsert: { updatedat: now, updates: 0 }},       upsert: true },     { q: { name: 'bob', updatedat: { $lt: } },       u: { $set: { updatedat: }, $inc: { updates: 1 } },       upsert: false },   ] }) {     "ok" : 1,     "nmodified" : 0,     "n" : 1,     "upserted" : [         {             "index" : 0,             "_id" : objectid("556f672cd418ed1506eb2ca3")         }     ] } 

then, when run again:

> var = new date() > db.runcommand({   update: 'users',   updates: [     { q: { name: 'bob' },       u: { $setoninsert: { updatedat: now, updates: 0 }},       upsert: true },     { q: { name: 'bob', updatedat: { $lt: } },       u: { $set: { updatedat: }, $inc: { updates: 1 } },       upsert: false },   ] }) { "ok" : 1, "nmodified" : 1, "n" : 2 } 

please note update command not atomic. there no way other client see partially created or updated user document either first update statement create populated document, or exists (and left untouched) until second statement updates completely.

it safe if user concurrently created between 2 statements -- transparently updated if needed.


Comments

Popular posts from this blog

javascript - Bootstrap Popover: iOS Safari strange behaviour -

Magento/PHP - Get phones on all members in a customer group -

session - Logging Out Using PHP -