【问题标题】:Aggregate sum with lookup to another collection汇总总和并查找另一个集合
【发布时间】:2017-06-28 16:59:12
【问题描述】:

我有两种模式,一种是User,另一种是PetPet 架构包含我想在 User.aggregate 管道内 $sum 的信息。

Mongo 版本是 3.4.1。

用户架构:

pets: [{type: Schema.Types.ObjectId, ref: 'Pets'}]

宠物架构:

      owner: {type: Schema.Types.ObjectId, ref: 'User'},
      petLost: {
       lost            : {type: Boolean, default: false},
       lostDate        : {type: String},
       selectedComRange: {type: Number, default: 5},
       circumstances   : {type: String},
       extraInfoLost   : {type: String},
       rewardCheck     : {type: Boolean, default: false},
       reward          : {type: String},
       addressLost     : {type: String},
      }

这是查找:

{'$unwind': '$pets'},
    {
      '$lookup': {
        'from'        : 'pets',
        'localField'  : '_id',
        'foreignField': '_id',
        'as'          : 'lostPets'
      }
    },
{'$unwind': {path: '$lostPets', preserveNullAndEmptyArrays:true}}

这是我想要达到的条件:

'lostPet_count': {
          '$sum': {
            '$cond': [{'$eq': ['$lostPets.lost', true]}, 1, 0]
          }
        } 

聚合管道:

User.aggregate([
        {
          $group: {
            _id              : null,
            'users_count'    : {
              '$sum': {
                '$cond': [{'$eq': ['$role', 'user']}, 1, 0]
              }
            },
            'volunteer_count': {
              '$sum': {
                '$cond': [{'$eq': ['$isVolunteer', true]}, 1, 0]
              }
            },
            'pet_count'      : {
              '$sum': {
                $size: '$pets'
              }
            },
            'lost_pet'       : {
              '$sum': {
                **// how can i call another collection and $sum some data?**
              }
            }
          }
        },
        {
          '$project': {
            '_id'       : 0, 'role': '$_id',
            'statistics': {
              'users'     : '$users_count',
              'volunteers': '$volunteer_count',
              'pets'      : '$pet_count'
            }
          }
        }
      ]).exec((err, result) => {
        if (err) {
          console.log(err);
        }
        res.status(200).json(result);
      });

如何将信息从 Pet 架构注入 'lost_pet' 属性?

【问题讨论】:

  • 看看$lookup
  • @felix 这就是我现在正在做的事情,如果我能做到,我会发回结果
  • 当我尝试使用 `{ '$unwind': '$pets'} 展开数组时,出现此错误:MongoError: The argument to $size must be an array, but was of type: objectId --- 这是架构类型:pets : [{type: Schema.Types.ObjectId, ref: 'Pets'}],

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

以下管道应返回所需的结果:

Pets.aggregate([
    {
        '$lookup': {
            'from': 'users',
            'localField': 'owner',
            'foreignField': '_id',
            'as': 'users'
        }
    },
    { '$unwind': { 'path': '$users', 'preserveNullAndEmptyArrays': true } },
    {
        '$group': {
            '_id': '$users._id',
            'users_count': {
                '$sum': {
                    '$cond': [{'$eq': ['$users.role', 'user']}, 1, 0]
                }
            },
            'volunteer_count'   : {
                '$sum': {
                    '$cond': ['$users.isVolunteer', 1, 0]
                }
            },
            'pet_count': { '$sum': 1 },
            'lost_pets': {
                '$sum': {
                    '$cond': ['$petLost.lost', 1, 0]
                }
            }       
        }
    },
    {
        '$project': {
            '_id': 0, 'role': '$_id',
            'statistics': {
                'users': '$users_count',
                'volunteers': '$volunteer_count',
                'pets': '$pet_count',
                'lostpets': '$lost_pets'
            }
        }
    }
]).exec((err, result) => {
    if (err) {
        console.log(err);
    }
    res.status(200).json(result);
});

或从User 模型聚合为

User.aggregate([
    { '$unwind': '$pets' },
    {
        '$lookup': {
            'from': 'pets',
            'localField': 'pets',
            'foreignField': '_id',
            'as': 'pets'
        }
    },
    { '$unwind': { 'path': '$pets', 'preserveNullAndEmptyArrays': true } }
    {
        '$group': {
            '_id': '$_id',
            'role': { '$first': '$role' },
            'isVolunteer': { '$first': '$isVolunteer' },
            'pet_count': { '$sum': 1 },
            'lost_pets': {
                '$sum': {
                    '$cond': ['$pets.petLost.lost', 1, 0]
                }
            }   
        }
    },
    {
        '$group': {
            '_id': null,
            'users_count': {
                '$sum': {
                    '$cond': [{'$eq': ['$role', 'user']}, 1, 0]
                }
            },
            'volunteer_count'   : {
                '$sum': {
                    '$cond': ['$isVolunteer', 1, 0]
                }
            },
            'pet_count': { '$sum': '$pet_count' },
            'lost_pets': { '$sum': '$lost_pets' }   
        }
    },
    {
      '$project': {
        '_id': 0, 'role': '$_id',
        'statistics': {
            'users': '$users_count',
            'volunteers': '$volunteer_count',
            'pets': '$pet_count',
            'lostpets': '$lost_pets'
        }
      }
    }
]).exec((err, result) => {
    if (err) {
        console.log(err);
    }
    res.status(200).json(result);
});

【讨论】:

  • 用户和 lostpets 为 0。我有角色为 user 的用户,并且丢失的宠物设置为 true。回复如下:[ { "role": null, "statistics": { "users": 0, "volunteers": 1, "pets": 1, "lostpets": 0 } } ] 编辑:用户似乎在工作,lostpets 仍然停留在 0
  • 您可以尝试从Pets 模型中聚合,如上所示。
猜你喜欢
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2015-06-18
  • 2019-02-08
相关资源
最近更新 更多