sestegra
sestegra

Reputation: 87

Get last insertion from a series

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

Answers (2)

JustLogin
JustLogin

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

Mr Tarsa
Mr Tarsa

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

Related Questions