[SOLVED] Getting the last document added to a collection

I have a collection and need to add a seq number that is incremented when a new document is added.

Maybe I’m going about this the wrong way, so let me know if I am, but I’ve got a helper method where I’m trying to return the last document entered with

Questions.findOne({ sort: { _id: -1 }}, { limit: 1})

Now, I feel like I should be putting emtpy curly braces before this more like

Questions.findOne({}, { sort: { _id: -1 }}, { limit: 1})

But when I do that in the meteor mongo shell I get errors.

However, when I do my first option I always only get ‘null’ for the value, never a document.

Anyway, I figure I use the helper to get the last document, then increment the value while gathering up other form values before adding the next item.

I want the sequence number so I can easily query for a random set of items later, and I don’t really have any other fields that would allow a random query.

Thanks for any help,

Questions.findOne(selector) only returns one result from the collection based on the selector and does not allow you to sort.

What you seem to be looking for is

Questions.find({}, { sort: { _id: -1 }}, { limit: 1}).fetch().pop()

but that can break if your find doesn’t return any results

1 Like

Ok, in meteor mongo shell, when I do

db.questions.find({}, { sort: { _id: -1 }}, { limit: 1});

just to start, I get this error:

Error: error: {
"waitedMS" : NumberLong(0),
"ok" : 0,
"errmsg" : "Unsupported projection option: sort: { _id: -1.0 }",
"code" : 2
}

Adding .fetch().pop() to the end, does not change the issue.

I feel like just the first part should give me the desired result.

I really just need the last seq number added so I can increment it for the next document added.

I have 2 questions in my collection right now, so I would expect to get the 2nd document with seq: 1, having started at 0.

So the syntax in meteor shell is different than the syntax in meteor mongo.

Meteor/Meteor shell:

Questions.find({}, { sort: { _id: -1 }, limit: 1 });

Mongo/Meteor Mongo:

db.questions.find({}).sort({ _id: -1 }).limit(1);

Ah! Awesome! So using what you gave me, and needing to get the value in javascript to modify it, I got this to work.

Questions.findOne({}, { sort: { _id: -1 }, limit: 1 });

Which actually gives me what I need.

Thanks to you both @vigorwebsolutions and @jamgold. I appreciate it.

2 Likes

what happen if insert 3 object at same time did this code return me all of them?

No, this will only return 1, the last 1 in the system. If you need more, you’ll have to change the value after limit.

limit: 3 would give the last 3, and so on.

As a PSA, since this got bumped near the top…

You probably are doing something wrong if you have a sequence number for forms, or change the form values like this. You probably want to “gather up all the form values” in a method, and assign their sequence numbers at the same time in a method. Otherwise, with even two concurrent users, you’ll probably run into repeated sequence numbers.

However, to answer the actual question of getting the last document that was added, it’s a coincidence that _id is a sequence (though not evenly) field.

If you ever want to “bake in” the results of a query, like “What was the last document I inserted” or whatever, just create a document for it! For example, whenever you insert into the documents, also update {"_id": "lastInsertedDocument"} to point to the entire document. This technique also applies for things like “What was the latest document the user edited?” or “Which document represents the current top post?”

You’ll soon discover that this gives you a lot more flexibility than queries, because you often need to edit the results of these things anyway for their special purposes. Further, because you’ve made the thing you need to be reactive to a lot simpler than a real query and instead a single document, it’ll be way faster with multiple concurrent users.

Not if you use an atomic MongoDB method, such as findOneAndUpdate.