I'm trying to atomically insert an empty document if the capped collection is empty or return the last naturally sorted document if not empty. Can I do this with findAndModify?
db.collection.findAndModify({
query: { _id: { $exists: true }},
sort: { $natural: -1 },
update: {},
upsert: true,
new: true
});
I would have expected this to either return the latest document (if the collection is non empty) or insert a new document if none exist, however, it inserts a blank document (without an _id) every single time it's called. Does findAndModify work with capped collections? I need the added document to have an _id.
Thanks.
-Scott
There is a flaw in your query logic. A findAndModify() with:
... will:
do an update on the last inserted record with an
_idsetOR
insert a new (empty) document if no existing document with an
_idis found.The update is going to replace your last inserted record with an empty one .. which presumably is not the intended outcome :).
You are seeing a completely empty document (no
_idfield) because capped collections have some exceptions to the behaviour for standard collections.In particular:
there is no requirement for an
_idfield by default; you can have one generated on the server by including the autoIndexId:true option tocreateCollection()there is no index on the
_idfield (note: you will want a unique index if using replication with a capped collection)Also note that documents in a capped collection must not grow in size or the update will fail
Refer to the Capped Collection Usage & Restrictions on the wiki for more info.