填充有限数量的文档

Populate limited amount of documents

本文关键字:文档 填充      更新时间:2023-09-26

考虑以下示例Schema

var BookSchema = new Schema({
    title: {
        type: String
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    }
});

假设我有10条记录在MongoDb的图书收集
当查询图书列表时,我想只填充前3本书

exports.list = function(req, res) {
    Book.find()
        .populate('user', 'displayName') //populate only top 3 books here (10 in db)
        .exec(function(err, books) {
            res.json(books);
        });
};

我该怎么做?

<标题> 更新

我想要所有10个文档,但只填充前3个;

不确定"前三名"意味着来自哪里,但如果您只想要"三本书",但是您确定(并且最好使用排序),那么您需要解决这个问题,以便只有"三个"结果被填充,其他结果不得到相同的处理。

因此,您可以在结果数组的"部分"结果中"内部"执行此操作:

Book.find().exec(function(err,books) {
    User.populate(
        books.slice(0,3),                            // get first 3 array items
        { "path": "user", "select": "displayName" }, // populate options
        function(err,part) {
            books = part.concat(books.slice(-(books.length-3)));
            console.log( JSON.stringify( books, undefined, 2 ) );
        }
    );
});

因此,正如您可以看到的那样,您可以通过手动调用User模型中的.populate()的形式,并且仅取您想要填充的数组响应的"部分",然后将其与整个响应重新连接起来。

作为一个更长的工作示例:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/poptest');
var items = [
  "one", "two", "three", "four","five",
  "six", "seven", "eight", "nine", "ten"
];
var itemSchema = new Schema({
  name: String
});
var dataSchema = new Schema({
  name: String,
  items: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var Item = mongoose.model( 'Item', itemSchema );
var Data = mongoose.model( 'Data', dataSchema );
async.series(
  [
    function(callback) {
      async.each([Item,Data],function(model,callback) {
        model.remove({},callback);
      },callback);
    },
    function(callback) {
      async.each([Item,Data],function(model,callback) {
        async.each(items,function(item,callback) {
          model.create({ name: item },callback);
        },callback);
      },callback);
    },
    function(callback) {
      async.waterfall(
        [
          function(callback) {
            Item.find({ name: { "$in": ["one","two","three"]  } })
              .exec(callback);
          },
          function(itemList,callback) {
            Data.find().exec(function(err,datas) {
              callback(err,itemList,datas);
            });
          },
          function(itemList,datas,callback) {
            async.each(datas,function(data,callback) {
              itemList.forEach(function(item) {
                data.items.push(item._id);
              });
              data.save(callback)
            },callback);
          }
        ],
        callback
      );
    },
    function(callback) {
      Data.find().exec(function(err,data) {
        if (err) callback(err);
        Item.populate(data.slice(0,3),'items',function(err,part) {
          if (err) callback(err);
          data = part.concat(data.slice(-(data.length-3)));
          console.log(data);
          callback()
        });
      });
    }
  ],
  function(err) {
    if (err) throw err;
    mongoose.disconnect();
  }
);

生成只显示前三个结果的输出:

[ { _id: 55dc369e584563b619de221e,
    name: 'one',
    __v: 1,
    items:
     [ { _id: 55dc369e584563b619de2214, name: 'one', __v: 0 },
       { _id: 55dc369e584563b619de2215, name: 'two', __v: 0 },
       { _id: 55dc369e584563b619de2216, name: 'three', __v: 0 } ] },
  { _id: 55dc369e584563b619de221f,
    name: 'two',
    __v: 1,
    items:
     [ { _id: 55dc369e584563b619de2214, name: 'one', __v: 0 },
       { _id: 55dc369e584563b619de2215, name: 'two', __v: 0 },
       { _id: 55dc369e584563b619de2216, name: 'three', __v: 0 } ] },
  { _id: 55dc369e584563b619de2220,
    name: 'three',
    __v: 1,
    items:
     [ { _id: 55dc369e584563b619de2214, name: 'one', __v: 0 },
       { _id: 55dc369e584563b619de2215, name: 'two', __v: 0 },
       { _id: 55dc369e584563b619de2216, name: 'three', __v: 0 } ] },
  { _id: 55dc369e584563b619de2221,
    name: 'four',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2222,
    name: 'five',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2223,
    name: 'six',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2224,
    name: 'seven',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2225,
    name: 'eight',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2226,
    name: 'nine',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] },
  { _id: 55dc369e584563b619de2227,
    name: 'ten',
    __v: 1,
    items:
     [ 55dc369e584563b619de2214,
       55dc369e584563b619de2215,
       55dc369e584563b619de2216 ] } ]

我认为你必须添加options属性:

exports.list = function (req, res) {
    Book.find()
    .populate({
        path: 'user',
        select: 'displayName',
        options: {
            limit: 3
        }
    }) //populate only top 3 books here (10 in db)
    .exec(function (err, books) {
        res.json(books);
    });
};