Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the latest and oldest record in mongoose.js (or just the timespan between them)

Basic problem

I have a bunch of records and I need to get latest (most recent) and the oldest (least recent).

When googling I found this topic where I saw a couple of queries:

// option 1 Tweet.findOne({}, [], { $orderby : { 'created_at' : -1 } }, function(err, post) {   console.log( post ); }); // option 2 Tweet.find({}, [], {sort:[['arrival',-1]]}, function(err, post) {   console.log( post ); }); 

Unfortunatly they both error:

TypeError: Invalid select() argument. Must be a string or object. 

The link also has this one:

Tweet.find().sort('_id','descending').limit(15).find(function(err, post) {   console.log( post ); }); 

and that one errors:

TypeError: Invalid sort() argument. Must be a string or object. 

So how can I get those records?

Timespan

Even more ideally I just want the difference in time (seconds?) between the oldest and the newest record, but I have no clue on how to start making a query like that.

This is the schema:

var Tweet = new Schema({     body: String   , fid: { type: String, index: { unique: true } }   , username: { type: String, index: true }   , userid: Number   , created_at: Date   , source: String }); 

I'm pretty sure I have the most recent version of mongoDB and mongoose.

EDIT

This is how I calc the timespan based on the answer provided by JohnnyHK:

var calcDays = function( cb ) {   var getOldest = function( cb ) {     Tweet.findOne({}, {}, { sort: { 'created_at' : 1 } }, function(err, post) {       cb( null, post.created_at.getTime() );     });   }     , getNewest = function( cb ) {     Tweet.findOne({}, {}, { sort: { 'created_at' : -1 } }, function(err, post) {       cb( null, post.created_at.getTime() );     });   }    async.parallel({      oldest: getOldest   , newest: getNewest   }     , function( err, results ) {       var days = ( results.newest - results.oldest ) / 1000 / 60 / 60 / 24;       // days = Math.round( days );       cb( null, days );     }   ); } 
like image 531
askmike Avatar asked Sep 17 '12 21:09

askmike


People also ask

What is the difference between id and _ID in Mongoose?

So, basically, the id getter returns a string representation of the document's _id (which is added to all MongoDB documents by default and have a default type of ObjectId ). Regarding what's better for referencing, that depends entirely on the context (i.e., do you want an ObjectId or a string ).

What does __ V mean in Mongoose?

The __v field is called the version key. It describes the internal revision of a document. This __v field is used to track the revisions of a document.

What is skip and limit in Mongoose?

The limit method will be used to return the maximum number of results from the collection, while the skip method is used to skip the number of documents from the collection in MongoDB. If we have one collection name as a student, student collection contains a hundred documents in it.

What does findById return in Mongoose?

findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .


2 Answers

Mongoose 3.x is complaining about the [] parameter in your findOne calls as the array format is no longer supported for the parameter that selects the fields to include.

Try this instead to find the newest:

Tweet.findOne({}, {}, { sort: { 'created_at' : -1 } }, function(err, post) {   console.log( post ); }); 

Change the -1 to a 1 to find the oldest.

But because you're not using any field selection, it's somewhat cleaner to chain a couple calls together:

Tweet.findOne().sort({created_at: -1}).exec(function(err, post) { ... }); 

Or even pass a string to sort:

Tweet.findOne().sort('-created_at').exec(function(err, post) { ... }); 
like image 189
JohnnyHK Avatar answered Sep 29 '22 15:09

JohnnyHK


Fast and Simple - One Line Solution

Get 10 latest documents

MySchema.find().sort({ _id: -1 }).limit(10) 

Get 10 oldest documents

MySchema.find().sort({ _id: 1 }).limit(10) 

In case you want sorting based on some other property i.e. createdAt and get the oldest or latest. It is similar to the above query.

MySchema.find().sort({ createdAt: -1 }).limit(10)  // 10 latest docs MySchema.find().sort({ createdAt: 1 }).limit(10) // 10 oldest docs 
like image 29
WasiF Avatar answered Sep 29 '22 15:09

WasiF