如何在 mongose.js 中获得最新和最古老的记录(或者只是它们之间的时间跨度)

基本问题

我有一堆记录,我需要得到最新的(最近的)和最老的(最近的)。

当我在谷歌上搜索时,我发现了 这个话题,在那里我看到了几个问题:

// 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 );
});

不幸的是,他们都犯了错误:

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

这个链接还有一个:

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

还有一个错误:

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

我怎么才能拿到那些记录?

时间跨度

更理想的情况是,我只想要时间上的差异(秒?)但是我不知道如何开始进行这样的查询。

这就是模式:

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

我很确定我有 mongoDB 和猫鼬的最新版本。

剪辑

以下是我根据 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 );
}
);
}
133186 次浏览

Mongoose 3.x 正在抱怨 findOne调用中的 []参数,因为选择要包含的字段的参数不再支持数组格式。

尝试下面的方法可以找到最新的:

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

-1更改为 1以查找最古老的。

但是因为您没有使用任何字段选择,所以将两个调用链接在一起会更简单一些:

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

或者甚至将一个字符串传递给 sort:

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

版本 ~ 3.8猫鼬

找到最后一条记录

model.findOne().sort({ field: 'asc', _id: -1 }).limit(1)

或使用

model.findOne().sort({ field: -_id }).limit(1)

我们有方法称为排序使用,我们可以使用 获取第一个元素(旧文档) ,表示排序字段为1Last element (new document)表示排序字段为 -1的收集。

collectionName.findOne().sort({$natural: -1}).limit(1).exec(function(err, res){
if(err){
console.log(err);
}
else{
console.log(res);
}
}

这将为您提供数据库中记录的最后一个文档。

快速简单的单线解决方案

接通 10 latest documents

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

接通 10 oldest documents

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

如果您希望基于其他属性(例如 createdAt)进行排序,那么可以获得最早或最新的。它类似于上面的查询。

MySchema.find().sort({ createdAt: -1 }).limit(10)  // 10 latest docs
MySchema.find().sort({ createdAt: 1 }).limit(10) // 10 oldest docs
await Model.find().sort({$natural:-1}).limit(1); //for the latest record
await Model.find().sort({$natural:1}).limit(1); //for the oldest record

这一个为我工作。使用蒙哥布自然秩序 https://docs.mongodb.com/manual/reference/operator/meta/natural/

下面是异步等待的答案

const olderDoc: any = await Model.findOne().sort({ createdAt: 1 }).lean().exec()
console.log('olderDoc', olderDoc)


const newerDoc: any = await Model.findOne().sort({ createdAt: -1 }).lean().exec()
console.log('newerDoc', newerDoc)

最好的方法是使用这样的异步函数:

async function findLastElement () {
return await Mymodel.findOne().sort('-_id');
}

通过这种方式,您可以获得最后一个元素,并确保可重用性。