Get n most recent documents based on objectId - mongodb

I am wondering if there is a way to order a result set based on the date component in an object Id
myCol.find().sort('_id descending').limit(5).select('title _id').exec(function(e, data){
res.render('some-page.html',{data:data});
});
I don't have an explicit date field in my documents, but it's my understanding that objectId already contains a date component, so I am wondering if I can take advantage of that here.
The above code will not correctly order the result set
EDIT:
By updating the query slightly I got it to work
myCol.find().sort([['_id', -1]])
Source: uses for mongodb ObjectId creation time

The simplest way to sort descending with Mongoose is to prefix the field name in your call so sort with a -:
myCol.find()
.sort('-_id')
.limit(5)
.select('title _id')
.exec(function(e, data){
res.render('some-page.html',{data:data});
});

Related

Sort documents in firestore collection chronologically

Is there a way to sort documents in collection chronologically when they are created? Currently, they are all over the place. For example, in To-Do app, when you add new item to collection, it should display at the bottom, last, not somewhere in the middle.
You will need to define an order based on some data in the document, and order your queries based on that field.
The typical solution for time-base order to make sure your documents all contain a timestamp field that you can use to sort them. When you call add() (or other methods to update data), you can tell Firestore to use the current time using FieldValue.serverTimestamp():
collection(...).add({
..., // your other fields
createdOn: FieldValue.serverTimestamp()
})
Then you can use that field to sort when querying with orderBy():
collection(...).orderBy('createdOn')
Try using DateTime.now() for the document ID. This should put the collection in chronological order.
For example:
Firestore.instance.collection('Posts').document(DateTime.now().toString()).setData({});

Firestore order by time but sort by ID

I have been trying to figure out a way to query a list of documents where I have a range filter on one field and order by another field which of course isn't possible, see my other question: Order by timestamp with range filter on different field Swift Firestore
But is it possible to save documents with the timestamp as id and then it would sort by default? Or maybe hardcode an ID, then retrieve the last created document id and increase id by one for the next post to be uploaded?
This shows how the documents is ordered in the collection
Any ideas how to store documents so they are ordered by created at in the collection?
It will order by document ID (ascending) by default in Swift.
You can use .order(by: '__id__') but the better/documented way is with FieldPath documentID() I don't really know Swift but I assume that it's something like...
.order(by: FirebaseFirestore.FieldPath.documentID())
JavaScript too has an internal variable which simply returns __id__.
.orderBy(firebase.firestore.FieldPath.documentId())
Interestingly enough __name__ also works, but that sorts the whole path, including the collection name (and also the id of course).
If I correctly understood your need, by doing the following you should get the correct order:
For each document, add a specific field of type number, called for example sortNbr and assign as value a timestamp you calculate (e.g. the epoch time, see Get Unix Epoch Time in Swift)
Then build a query sorted on this field value, like:
let docRef = db.collection("xxxx")
docRef.order(by: "sortNbr")
See the doc here: https://firebase.google.com/docs/firestore/query-data/order-limit-data
Yes, you can do this.
By default, a query retrieves all documents that satisfy the query in
ascending order by document ID.
See the docs here: https://firebase.google.com/docs/firestore/query-data/order-limit-data
So if you find a way to use a timestamp or other primary key value where the ascending lexicographical ordering is what you want, you can filter by any fields and still have the results sorted by the primary key, ascending.
Be careful to zero-pad your numbers to the maximum precision if using a numeric key like seconds since epoch or an integer sequence. 10 is lexicographical less than 2, but 10 is greater than 02.
Using ISO formatted YYYY-mm-ddTHH:MM:SS date-time strings would work, because they sort naturally in ascending order.
The order of the documents shown in the Firebase console is mostly irrelevant to the functioning of your code that uses Firestore. The console is just for browsing data, and that sorting scheme makes it relatively intuitive to find a document you might be looking for, if you know its ID. You can't change this sort order in the console.
Your code is obviously going to have other requirements, and those requirements should be coded into your queries, without regarding any sort order you see in the dashboard. If you want time-based ordering of your documents, you'll have to store some sort of timestamp field in the document, and use that for ordering. I don't recommend using the timestamp as the ID of a document, as that could cause problems for you in the future.

Can't find documents by criteria containing string objectId value

I have a collection list such:
{username: 'somename',
friendId: '57d725d6b8b144044602bf74' <-- This a reference objectId to another doc
}
When I query docs in my collection with criteria {friendId : '57d725d6b8b144044602bf74'} I get no results back .
Any other field query works fine.
I tried to convert the value to ObjectId('57d725d6b8b144044602bf74') even though the value is just a string, still no go.
Why am I failing to search for by that type of string ?
you are trying to achieve 'self-join' in mongoDB and you seems to rely on the _id field generated by mongodb.
i would suggest you to supply custom _ID fields to the document.
eg:
{_id:"alex", name:"alex", friendID:""}
{_id"john", name"john", friendID:"alex"}
and then you can execute your queries with ease on friendID field. Give it a shot and see if this make sense for your requirement.

querying documents in a date range using Mongo built-in 'timestamp'

I'm aware that the Mongo "ObjectId" has the method "getTimestamp()" , which works like
ObjectId("507f191e810c19729de860ea").getTimestamp()
And also I'm aware that it can be sorted based on built-in 'timestamp'
db.collection.find().sort({'timestamp': -1})
I know I can create a new field "created_time" in each document by converting ObjectId to created_time, then query based on this new field.
I've also read this post which converts the date range to ObjectId and then directly compare the ObjectId, but this method I'm worried about the other bytes which is not for time but for machine and process.
My question is, is there a way to directly query documents in a date range using Mongo built-in 'timestamp'? without extra field or extra effort.
something like below (but I tried below command and not working), which can directly query Mongo using its built-in timestamp.
db.collection.find({'timestamp':{$gt: new Date(ISODate("2015-08-14T14:00:00Z"))}})

Sort collection by insertion datetime using only id field

I have a collection of data and I want to get it sorted by insertion time. I have not any additional fields to store the insert time. But as I found out I can get this time from Id.
I have tried this code:
return bookmarks.find({}, {sort: {_id.getTimestamp(): 1}, limit: 10});
or
return bookmarks.find({}, {sort: {ObjectId(_id).getTimestamp(): 1}, limit: 10});
but get the error message:
=> Your application has errors. Waiting for file change.
Is there any way to sort collection by insertion datetime using only id field ?
At the moment this isn't possible with Meteor, even if it is with MongoDB. The ObjectID's created with meteor don't bear a timestamp. See http://docs.meteor.com/#collection_object_id
The reason for this is client side code can insert code and it can arrive late on the server, hence there is no guarantee the timestamp portion of the ObjectID will be accurate. In addition to the latency the client side's date is used meaning if they're off it's going to get you incorrect data. I think this is the reason they use an ObjectID but it is completely random.
If you want to sort by date you have to store the time/date separately.
The part what i striked out is not accurate. Meteor use it is own id generation which is based on a random string that is while does not apply the doc what i linked before. Check sasha.sochka's comment under.
It is nearly but not 100% good if you just sort for the _id field . While as it is constructed the first 4 byte is the timestamp in secs (so sorting for the getTimestamps value is not better). Under one second resolution you cannot get the exact order, as it is mentioned in the documentation: http://docs.mongodb.org/manual/reference/object-id/#objectid
It is still true that you can try to check the exact order of the insert/update ops against your collection in the oplog, if you have an oplog, but as it is a capped collection anyway you will see the recent operations only. http://docs.mongodb.org/manual/core/replica-set-oplog/.