可以找到第一个或最后一个匹配?

时间:2014-07-16 23:56:05

标签: javascript mongodb mongoose queue

我特意使用猫鼬,虽然我不相信那么重要。例如,假设我有一个名为MongoQueue的集合,我在该队列中添加了一些人。

`MongoQueue.save {function(err, firstPerson) {
   if (err) console.log(err);
   MongoQueue.save {function(err, secondPerson) {
      if (err) console.log(err);
      MongoQueue.save {function(err, thirdPerson) {
         if (err) console.log(err);
}}}`


如何检索首次保存到MongoQueue的人?或者...... mongoDB的findOne()方法如何缩小它的搜索范围?我可以指定findOne()的行为来选择集合中最旧的文档吗?或者我必须对集合进行排序(这将是最后的手段),如果是这样,我将如何按时间戳排序?

2 个答案:

答案 0 :(得分:1)

是的,您可以指定.findOne()的行为,最好在本机驱动程序文档中显示。唯一的区别是,在mongoose实现中,“选项”文档必须是传递给该方法的“第三”参数。

因此,您可以为此提供“排序”规范,如可用选项中所示:

Queue.findOne({ },null,{ "sort": { "_id": -1 } },function(err,doc) {

只是为了获取更多信息,您可以使用$orderby查询选项在MongoDB shell中执行此操作:

db.collection.findOne({ "$query": { }, "$orderby": { "_id": -1 } })

同样,.findOne()方法可能只返回一个文档,但它实际上只是.find()的包装,因此所有修饰符都适用。包装只是在返回的光标上调用.next(),返回文档并丢弃光标。

这个较长的例子显示了可以应用的不同方式:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;


mongoose.connect('mongodb://localhost/sequence');

var queueSchema = new Schema({
  name: String,
  same: { type: String, default: "same" }
});

var Queue = mongoose.model( "Queue", queueSchema );

var count = 0;

async.series(
  [

    // Remove any documents
    function(callback) {
      Queue.remove(function(err) {
        if (err) throw err;
        callback();
      });
    },

    // Insert some new ones
    function(callback) {
      async.eachSeries(
        ["one","two","three"],
        function(item,callback) {
          var queue = new Queue({ name: item });
          queue.save(function(err,doc) {
            if (err) throw err;
            console.dir(doc);
            callback(err,doc);
          });
        },
        function(err) {
          callback(err);
        }
      );
    },

    function(callback) {
      async.whilst(
        function() { return count < 2 },
        function(callback) {
          count++
          async.series(
            [
              // findOne is just the first one
              function(callback) {
                Queue.findOne({ "same": "same" },function(err,doc) {
                  if (err) throw err;
                  console.log( "FindOne:\n%s", doc );
                  callback();
                });
              },

              // Or is sorted
              function(callback) {
                Queue.findOne(
                  { "same": "same" },
                  null,
                  { "sort": { "_id": -1 } },
                  function(err,doc) {
                    if (err) throw err;
                    console.log("FindOne last:\n%s", doc );
                    callback();
                  }
                );
              },

              // find is ordered but not singular
              function(callback) {
                async.eachSeries(
                  ["first","last"],
                  function(label,callback) {
                    var direction = ( label == "first" ) ? 1 : -1;
                    var query = Queue.find({ "same": "same" })
                      .sort({ "_id": direction })
                      .limit(1);
                    query.exec(function(err,docs) {
                      if (err) throw err;
                      console.log( ".find() %s:\n%s", label, docs[0] );
                      callback();
                    });
                  },
                  function(err) {
                    callback();
                  }
                );
              },

              // findAndModify takes a sort
              function(callback) {
                Queue.findOneAndUpdate(
                  { "same": "same" },
                  { "$set": { "same": "different" } },
                  { "sort": { "_id": -1 } },
                  function(err,doc) {
                    if (err) throw err;
                    console.log( "findOneAndUpdate:\n%s", doc );
                    callback();
                  }
                );
              }

            ],function(err) {
              callback();
            }
          );
        },
        function(err) {
          callback();
        }
      );
    }
  ],function(err) {
    console.log("done");1
    mongoose.disconnect();
  }
);

答案 1 :(得分:0)

findOne()函数返回natural order中的文档,这是磁盘上的顺序。您不能指望这返回最近插入的文档。要返回最近插入的文档,可以使用find()函数对_id进行反向排序,限制为1,假设_id是为您生成的默认ObjectId,或者在时间戳上(_id是部分构建的)从时间戳开始,这就是为什么它适用于_id)。如果你使用_id(总是被索引)或索引时间戳字段,这将非常快。