通过匹配多个Id值的相同字段来聚合查询

时间:2017-08-25 08:31:46

标签: javascript node.js mongodb mongoose aggregation-framework

我有预订模式,预订由多个客户完成。

    var booking = new Schema({
     booking: {

         start_time : { type: Date },
         end_time :  { type: Date },
         park_location_id: {  type: Schema.Types.ObjectId },
         clientId:  {  type: Schema.Types.ObjectId },
  }
});

这里我正在寻找一种方法,我可以在一个数组中传递多个clientId,并为所有这些客户端执行聚合,并在一个查询中获取聚合结果。现在我正在执行循环操作来获取每个结果客户端。

    booking.statics.totalCheckinReport = function(id,callback){ 
   // Here id is single client
   // can I pass an array of clientID as [ id1, id2,id3]
   // and get the aggregated result of all of them
        this.aggregate([
            {
                $match:
                    {
                        $and:[
                            {'booking.park_location_id' : mongoose.Types.ObjectId(id)}
                        ]
                    }
            },
            {
                $group :{
                    _id : id,
                    totalCheckinCount: { $sum : 1 },
                }
            }
            ]).exec(function(err, data){
              if(err)
                 callback(null,err);
              else
                callback(null, data);
         })
    }

有没有更好的方法来做到这一点,而无需循环遍历clientsID并将其传递给我的mongoose函数。

1 个答案:

答案 0 :(得分:1)

基本上只需将$in应用于值列表,并实际使用"字段值"而不是静态值"对于分组_id。因为写"$group": { "_id": id也可能是"$group": { "_id": null。使用"字段值"可以获得更多效用。代替:

    booking.statics.totalCheckinReport = function(ids,callback){
        // using ids as an array as input
        ids = ids.map( id => mongoose.Types.ObjectId(id) ); // Cast each array member
        this.aggregate([
          { $match:{
            'booking.park_location_id' : { $in: ids }
          }},
          { $group :{
            _id : '$booking.park_location_id'  // <-- Actually use the field value
            totalCheckinCount: { $sum : 1 },
          }}
        ]).exec(callback)                     // <-- this already passes the error
                                              // and result
    }

呼叫

Booking.totalCheckinReport([id1,id2,id3],function(err,result) {
  // deal with response here
});

另请注意,显式$and(即使您确实拥有多个参数)几乎从未实际需要。所有论据实际上已经是&#34; AND&#34;条件,并且只要条件被指定为&#34;单独的键&#34;那么就不需要&#34;阵列形式&#34;参数。