Reputation: 3026
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
Upvotes: 1
Views: 2036
Reputation: 65333
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?
There is a flaw in your query logic. A findAndModify() with:
query: { _id: { $exists: true }}, sort: { $natural: -1 }, update: {}, upsert: true, new: true
... will:
do an update on the last inserted record with an _id
set
OR
insert a new (empty) document if no existing document with an _id
is 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 _id
field) because capped collections have some exceptions to the behaviour for standard collections.
In particular:
there is no requirement for an _id
field by default; you can have one generated on the server by including the autoIndexId:true option to createCollection()
there is no index on the _id
field (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.
Upvotes: 1