67

基本问题

我有一堆记录,我需要获取最新的(最近的)和最旧的(最近的)。

谷歌搜索时,我发现了这个主题,在那里我看到了几个查询:

// 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 和 mongoose。

编辑

这就是我根据 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 );
    }
  );
}
4

8 回答 8

129

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

试试这个来找到最新的:

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

将 更改-1为 a1以查找最旧的。

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

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

甚至将字符串传递给sort

Tweet.findOne().sort('-created_at').exec(function(err, post) { ... });
于 2012-09-17T21:16:48.703 回答
49

快速简单 - 一条线解决方案

得到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
于 2019-02-18T06:15:55.890 回答
14

对于版本 ~3.8 mongoose

找到最后一个条目

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

或使用

model.findOne().sort({ field: -_id }).limit(1)
于 2017-10-21T07:36:59.917 回答
5
collectionName.findOne().sort({$natural: -1}).limit(1).exec(function(err, res){
    if(err){
        console.log(err);
    }
    else{
        console.log(res);
    }
}

这将为您提供数据库中记录的最后一个文档。只需遵循相同的概念。

于 2018-12-17T17:01:41.657 回答
3
await Model.find().sort({$natural:-1}).limit(1); //for the latest record
await Model.find().sort({$natural:1}).limit(1); //for the oldest record

这个对我有用。使用 mongodb 自然顺序https://docs.mongodb.com/manual/reference/operator/meta/natural/

于 2021-04-04T13:53:48.243 回答
1

我们有一个称为 sort 的方法,使用它我们可以获得第一个元素(旧文档),这意味着 1 用于排序字段最后一个元素(新文档),这意味着 -1 用于集合的排序字段。

于 2018-10-12T03:24:43.707 回答
0

这是异步的答案 - 等待

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)
于 2021-12-15T11:24:10.243 回答
0

最好的方法是有一个这样的异步函数:

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

这样你就得到了最后一个元素并确保了可重用性。

于 2022-02-02T19:37:08.400 回答