Reputation: 87
I'm building a series of data for each user using my application.
The document format is following
{ "userId": String, "timestamp": DateTime, "data": Data }
I'm looking for a simple query to get last inserted data (with "timestamp") for a list of users (with "userId").
See my current implementation.
userIds.forEach(function(id){
db.data.find({"userId":id}).sort({"timestamp":-1}).limit(1);
});
Upvotes: 0
Views: 54
Reputation: 1890
You can state multiple users in query, sort them by timestamp and return just one. Just like this:
db.users.find({userId: {$in:[your_list_ids]}}, {fields_you_need}).sort({timestamp: -1}).limit(1)
So, this request finds all users in group (everyone, whose userId is in array), then sorts them descendingly by "timestamp" field and limits your output with 1 record.
Remember! To keep sortings fast, you have to apply index to sorted field.
Upvotes: 0
Reputation: 6652
You can use aggregation-framework
to accomplish it. Aggregation pipeline with one $group
stage and $max
operator on timestamp
field
db.yourCollection.aggregate(
{ $group: { _id: "$userId", "last": { $max: "$timestamp" } } }
);
for collection of documents
{ "userId" : "1", "timestamp" : 1470385420806, "data" : "123" }
{ "userId" : "1", "timestamp" : 1470386440616, "data" : "456" }
{ "userId" : "2", "timestamp" : 1470385598845, "data" : "222" }
{ "userId" : "2", "timestamp" : 1470385602249, "data" : "333" }
will give you the result
{ "_id" : "1", "last" : 1470386440616 }
{ "_id" : "2", "last" : 1470385602249 }
that seems to be what you expect.
Upvotes: 3