连接两个集合并在Mongoose中对它们进行排序

Join two collections and sort them in Mongoose

本文关键字:排序 Mongoose 两个 合并 集合 连接      更新时间:2023-09-26

我有两个独立的集合,假设newspictures。两个集合都有一个creationDate字段,该字段保存记录创建时间的datetime

我想要的是从两个集合中选择最后10条记录,连接所有记录(现在列表有20条记录),然后按creationDate字段对所有记录进行排序。猫鼬怎么可能呢?

你所要求的本质上是一个客户端操作,你真的只需要最多20个记录排序,所以这应该不是一个问题。

异步。Concat方法在这里应该有一点帮助:

async.concat([News,Picture],function(model,callback) {
  // Get the last 10 results from each collection
  var query = model.find({}).sort({ "creationDate": -1 }).limit(10);
  query.exec(function(err,docs) {
    if (err) throw err;
    callback(err,docs);
  });
},
function(err,result) {
  if (err) throw err;
  // results are merged, now sort by date
  result = result.sort(function(a,b) {
    return (a.creationDate < b.creationDate) 
      ? 1 : (a.creationDate > b.creationDate) ? -1 : 0;
  });
  console.log(result);
});

所以实际上你只是在"合并"两个数组,但是这样编码会简化事情。


一个端到端清单来澄清这里的用法。在运行如上所示的代码之前,这会为每个模型设置一些文档:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/series');
var newsSchema = new Schema({
  type: { type: String, default: "News" },
  index: Number,
  creationDate: { type: Date, default: Date.now }
});
var pictureSchema = new Schema({
  type: { type: String, default: "Picture" },
  index: Number,
  creationDate: { type: Date, default: Date.now }
});
var News = mongoose.model( "News", newsSchema );
var Picture = mongoose.model( "Picture", pictureSchema );
async.series(
  [
    // Clean existing
    function(callback) {
      async.each([News,Picture],function(model,callback) {
        model.remove(function(err) {
          if (err) throw err;
          callback();
        });
      },function(err) {
        callback();
      });
    },
    // Insert 20 of each
    function(callback) {
      console.log("inserting");
      var count = 0;
      async.whilst(
        function() { return count < 20 },
        function(callback) {
          count++;
          async.eachSeries([News,Picture],function(model,callback) {
            var doc = new model({ index: count });
            setTimeout(function() {
              doc.save(function(err) {
                if (err) throw err;
                callback();
              });
            }, 20);
          },function(err) {
            callback();
          });
        },
        function(err) {
          callback();
        }
      );
    }
  ],
  function(err) {
    console.log("listing");
    // Get the last 10 of each
    async.concat([News,Picture],function(model,callback) {
      var query = model.find({}).sort({ "creationDate": -1 }).limit(10);
      query.exec(function(err,docs) {
        if (err) throw err;
        callback(err,docs);
      });
    },
    function(err,result) {
      if (err) throw err;
      // result is merged via "concat" now sort it.
      result = result.sort(function(a,b) {
        return (a.creationDate < b.creationDate)
          ? 1 : (a.creationDate > b.creationDate)
          ? -1 : 0;
      });
      console.log(result);
      mongoose.disconnect();
    });
  }
);

输出如下:

[ { _id: 53c79f4b7daf2d676ff0f185,
    index: 20,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'Picture' },
  { _id: 53c79f4b7daf2d676ff0f184,
    index: 20,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'News' },
  { _id: 53c79f4b7daf2d676ff0f183,
    index: 19,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'Picture' },
  { _id: 53c79f4b7daf2d676ff0f182,
    index: 19,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'News' },
  { _id: 53c79f4b7daf2d676ff0f181,
    index: 18,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'Picture' },
  { _id: 53c79f4b7daf2d676ff0f180,
    index: 18,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'News' },
  { _id: 53c79f4b7daf2d676ff0f17f,
    index: 17,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'Picture' },
  { _id: 53c79f4b7daf2d676ff0f17e,
    index: 17,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'News' },
  { _id: 53c79f4b7daf2d676ff0f17d,
    index: 16,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'Picture' },
  { _id: 53c79f4b7daf2d676ff0f17c,
    index: 16,
    __v: 0,
    creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
    type: 'News' } ]