I need to select from my messages collection, the 10 most recent messages, and return them as an array form the older to the most recent.
Example : m1, m2, m3, ... [m19, m20, m22] <-- Select last 10 but keep the order.
The slice operator is great because it can take value like -10 and so select 10 last values from an array. The problem is that I want to sort the whole query response, and not a property within the response (slice operator takes 2 arguments, the first one is the path).
Actually what I do is :
.find({ conversation: conversationId })
.sort('-updatedAt')
.limit(10)
.exec(function(err, messages) {
});
But the array it returns contains messages from the most recent to the older.
What can I do to keep the good order, without reverting the whole array after the query execution ? ( messages.reverse(); )
Get 10 latest documents
MySchema.find().sort({ _id: -1 }).limit(10)
Get 10 oldest documents
MySchema.find().sort({ _id: 1 }).limit(10)
You could change the order to ascending(old-to-new) messages and get the last N elements that you need
.find().skip(db.collection.count() - N)
So you will get the most recent messages in ascending orden
Related
Currently I working on a news feed and want to fetch more data when the user scrolls down the list. At first I get a specific amount of data from my server sorted by date like this ->
var newsFeed = await NewsFeed.find().sort({createdDate: 'desc'}).limit(parseInt(amount));
When the user know reach the end of the list, I want to load more data by simply increase the amount variable in my api call. With the current call I also get the first elements that I already have. So is there a solution to get like the first 10 documents sorted by date and when from 11 - 20 and so on ?
If your documents are sorted you can use skip.
For example, if you have 10 objects, like this:
{ id:1 }, { id:2 }, { id:3 }, { id:4 } , ... { id:n}
You can query the number of documents you want in this way:
var find = await model.find({}).sort({id:1}).limit(amount)
Then, to get the next values, you can do this query:
find = await model.find({}).sort({id:1}).skip(amount).limit(amount)
The first find (assuming amount is, for example, 2), will return documents wit id 1 and 2.
The second find will return id 3 and 4.
Also, check this stack overflow question and this docs from Mongo.
I have a data set that looks similar to this:
{"user":333,"product":943, "rating":2.025743791177902, "timestamp":1481675659}
{"user":333,"product":3074,"rating":2.1070657532324493,"timestamp":1481675178}
{"user":333,"product":3074,"rating":2.108323259636257, "timestamp":1481673546}
{"user":333,"product":943, "rating":2.0211849667268353,"timestamp":1481675178}
{"user":333,"product":943, "rating":2.041045323231024, "timestamp":1481673546}
{"user":333,"product":119, "rating":2.1832303461543163,"timestamp":1481675659}
{"user":333,"product":119, "rating":2.1937538029700203,"timestamp":1481673546}
{"user":111,"product":123, ...
I would like to query all records for a user (e.g. 333), but only return the latest timestamp:
{"user":333,"product":119, "rating":2.1832303461543163,"timestamp":1481675659}
Is this possible with a map/reduce index? If so, how?
Ideally I would also like to sort by the rating value.
If you create a Map function like this
function(doc) {
emit([doc.user, doc.timestamp], null);
}
an index would be created in user & time order.
To return the latest (most recent) timestamp for a given user you can query the index with the following parameters:
startkey=[333,9999999999]
endkey=[333,0]
descending=true
limit=1
We are querying the index in reverse order, starting with the largest timestamp for that user but limiting the result set size to 1 - the newest entry.
I have started creating a small chat application,since im using mongodb i started to implement with $slice for getting only latest 10 messages in my chat history. but the issue is that im not able get the latest set of data{10 messages},(data mismatch happens for every instance) . please any one help me out .
You might need to use a negative value to retrieve the latest elements.
From the $slice docs:
$slice accepts arguments in a number of formats, including negative values and arrays. Consider the following examples:
db.posts.find( {}, { comments: { $slice: 5 } } )
Here, $slice selects the first five items in an array in the comments field.
db.posts.find( {}, { comments: { $slice: -5 } } )
This operation returns the last five items in array.
i am trying to limit the number of records returned in a query:
Property.find(searchParams).nin('_id', prop_ids).limit(5).exec(function(err, properties) {
when the first call comes in, i get 5 records back. then i make a second call and pass in an array of ids (prop_ids). This array has all of the ids that were records that were returned in the first call... in this case i get no records back. I have a total of 7 records in my database, so the second call should return 2 records. How should I go about doing this?
I think mongoose might apply the limit before the nin query is applied so you will always just get those five. If it's a type of pagination you want to perform where you get 5 objects and then get 5 others, you can use the option skip instead:
var SKIP = ... // 0, 5, 10...
Property.find(searchParams, null, {
skip: SKIP,
limit: 5,
}, function(err, properties) {
})
This is what I took from your question, maybe you had something other in mind with the nin call?
I'm using mongo as my data store for a list of messages sent. Each message has an id and what I would like to be able to do (as efficiently as possible) is return n number of results starting before a supplied id going in reverse.
So, for example, with a function call like:
getHistory(start, count)
I could supply:
getHistory("a123", 10)
Which would return 10 records prior to the record with 'id="a123"`. Trick is the ID's are GUID and so I can't just increment backward based on that.
This is what I have so far and it's not starting in the correct position:
var cursor = collection.find({id: id}).sort({timestamp: -1}).limit(10)
Not tested, but something along the following lines should work (in mongoose):
collection.find({_id: {$lt: start}}).sort({_id: -1}).limit(10);
This should find all elements before the start id, reverse the order and get the first 10. In other words the last 10 before start.