Node.js 获取匹配文档的总计数以及满足特定条件的子集内的计数

Node.js 获取匹配文档的总计数以及满足特定条件的子集内的计数,node.js,mongodb,Node.js,Mongodb,假设我收集了以下5个文档: {"account_id": 11, "event": ISODate("2021-05-03T10:33:18.220Z")}, {"account_id": 11, "event": ISODate("2021-05-03T10:33:19.220Z")}, {"account_id": 11, "event&quo

假设我收集了以下5个文档:

{"account_id": 11, "event": ISODate("2021-05-03T10:33:18.220Z")},
{"account_id": 11, "event": ISODate("2021-05-03T10:33:19.220Z")},
{"account_id": 11, "event": null},
{"account_id": 99, "event": ISODate("2021-05-03T10:33:20.220Z")},
{"account_id": 99, "event": null}
在单个
聚合
查询中,我要检索:

  • 帐户id为11的文档总数(3)
  • account\u id:11
    事件
    不为空的文档总数(2)
  • 基本上,我所寻找的结果是:

    { total: 3, with_event: 2 }
    
    下面是满足上述第二点的代码。它匹配帐户id和事件类型9,即Mongo中的日期时间。如何扩展此代码以同时满足第1点

    mongo.accounts.aggregate([
        {
            "$match": {
                "account_id": 11,
                "event": {
                    "$type": 9
                }
            }
        },
        {
            "$group": {
                "_id": null,
                "count": {
                    "$sum": 1
                }
            }
        }
    ])
    

    您可以使用
    $facet
    运算符来分离条件和结果

    • $match
      帐户id的条件
    • 总计
      $group
      按空和合计文档
    • 带有事件
      按null匹配事件和
      $group
      并计算文档总数
    • $project
      要显示必填字段,请从facet结果中获取第一个元素


    第二种方法:

    • $match
      帐户id的条件
    • $group
      按null并获取
      总计
      文档,对于
      事件
      检查条件,如果类型为日期,则计数1,否则为0

    谢谢您的帮助。你认为哪一个会有更好的表现?我认为第二个,你可以按州检查表现。
    mongo.accounts.aggregate([
      { $match: { account_id: 11 } },
      {
        $facet: {
          total: [
            {
              $group: {
                _id: null,
                count: { $sum: 1 }
              }
            }
          ],
          with_event: [
            { $match: { event: { $type: 9 } } },
            {
              $group: {
                _id: null,
                count: { $sum: 1 }
              }
            }
          ]
        }
      },
      {
        $project: {
          total: { $arrayElemAt: ["$total.count", 0] },
          with_event: { $arrayElemAt: ["$with_event.count", 0] }
        }
      }
    ])
    
    mongo.accounts.aggregate([
      { $match: { account_id: 11 } },
      {
        $group: {
          _id: null,
          total: { $sum: 1 },
          with_event: {
            $sum: {
              $cond: [{ $eq: [{ $type: "$event" }, "date"] }, 1, 0]
            }
          }
        }
      }
    ])