MongoDB:动态计数

时间:2019-04-04 11:48:23

标签: node.js mongodb mongoose aggregation-framework

我有两个收藏。 “用户”集合和“事件”集合。事件集合上有一个主键,用于指示事件属于哪个用户。

我想计算用户符合特定条件的事件数。

当前,我正在执行以下操作:


db.users.find({ usersMatchingACondition }).forEach(user => {

  const eventCount = db.events.find({
    title: 'An event title that I want to find',
    userId: user._id
  }).count();

  print(`This user has ${eventCount} events`);

});

理想情况下,我想返回的是具有UserID的数组或对象以及该用户具有多少事件。

拥有10,000个用户-显然会产生10,000个查询,我认为它可以提高效率!

我认为使用某种汇总查询很容易-但是我对语法不熟悉,并且正在努力将其包裹住。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

您需要$lookup才能从events匹配的user_id中获取数据。然后,您可以使用$filter来应用事件级条件并获得计数,您可以使用$size运算符

db.users.aggregate([
    {
        $match: { //users matching condition }
    },
    {
        $lookup:
        {
            from: 'events',
            localField: '_id', //your "primary key"
            foreignField: 'user_id',
            as: 'user_events'
        }
    },
    {
        $addFields: {
            user_events: {
                $filter: {
                    input: "$user_events",
                    cond: {
                        $eq: [
                            '$$this.title', 'An event title that I want to find'
                        ]
                    }
                }
            }
        }
    },
    {
        $project: {
            _id: 1,
            // other fields you want to retrieve: 1,
            totalEvents: { $size: "$user_events" }
        }
    }
])

答案 1 :(得分:0)

没有聚合就无法完成很多优化,但是由于您是专门说的

首先,而不是

const eventCount = db.events.find({
    title: 'An event title that I want to find',
    userId: user._id
  }).count();

const eventCount = db.events.count({
    title: 'An event title that I want to find',
    userId: user._id
  });

这将大大加快您的查询速度,因为查找查询实际上首先会获取文档,然后进行计数。

要返回数组,您只需在开始处初始化一个数组,然后将{userid:id,count:eventCount}个对象推入该数组即可。