Mongoose populate选项limit,如何限制子文档的数量?

3
我有一个查询需求,需要查找一个账户并填充账户的子文档。
当我使用populate path:"orders"时,limit选项可以正常工作。但是,如果我使用populate path"orders.order",limit选项将无法工作。
我该怎么办?
我的模式如下:
  var AccountSchema = new mongoose.Schema({

    _id:id,
    orders:{type:[{
      order:{type: mongoose.Schema.Types.ObjectId, ref:'Order'}
    }]}
  });


var findOrderByUserId = function(accountId,index,count,callback){
  var limit = index*count;
  console.log(limit);
  Account.findOne({_id:accountId}).populate({
    path:'orders.order',//If path is orders, then limit will work

    options:{
      limit:limit
    }
  }).exec(function (err, doc) {
              if (err) {
                console.log(err);
                callback(err);
              }
              console.log(doc);
                var array = [];
                for(var i=limit - count;i<doc.orders.length;i++){
                    if(doc.orders[i]!=null){
                        array.push(doc.orders[i]);            
                    }
                    else{
                      break;
                    }
                }
              callback(doc);
          })
}

我对mongoose不是很熟悉,但为了限制子文档的数量,我们使用$slice操作符。https://docs.mongodb.com/manual/reference/operator/projection/slice/ - Ali Dehghani
还可以参考这个问题的解答:https://dev59.com/J4Dba4cB1Zd3GeqPK_bd - Ali Dehghani
1
谢谢,我认为您可以回答问题而不是发表评论 :) - Yan Li
我太懒了,不想写答案 :) - Ali Dehghani
2个回答

6

limit只能控制顶层文档,在文档内部控制数组需要使用$slice,这意味着您需要重新构建查询,如下所示(mongo shell):

db.posts.find( {}, { comments: { $slice: 5 } } )

请查看此帖子了解更多信息-并示例:

query.slice('comments', 5)
// or...
query.where('comments').slice(5)

manual


1
你的帖子可能需要一些格式化,不过回答很棒 :) - chridam

4

针对可能关注此问题的人,我注意到在使用mongoose population时,slice存在一个棘手的问题。

例如,我们有两个模型,分别称为UserGroupModel和UserModel。

var UserGroupSchema = new mongoose.Schema({
    users:[{type:mongoose.Schema.Types.ObjectId,ref:'User'}],
    groupName:String
})

var UserSchema = new mongoose.Schema({
    username:String
})

现在我们想要将用户填充到用户组中,出于性能考虑,我们只想要最后的20个用户。

在这里,像这样的代码是不起作用的

UserGroupModel.findById(userGroupId)
    .populate('users', 'username')
    .slice('users', -20)
    .select('users')
    .lean()
    .exec(function(err, group){})

你会注意到slice函数不起作用了,并且你需要改变为

UserGroupModel.findById(userGroupId)
    .populate('users', 'username')
    .slice('users', -20)
    .select('-groupName')
    .lean()
    .exec(function(err, group){})

重点是,如果你想对人口进行切片,你必须使用排除方法。
PS。“mongoose”:“4.4.15”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接