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
Post a Comment