【问题标题】:Get total count of matching documents and count within that subset that satisfies certain criteria获取匹配文档的总数并在满足特定条件的子集中计数
【发布时间】:2021-05-05 18:03:05
【问题描述】:

假设我在一个集合中有以下 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}

在我想检索的单个 aggregate 查询中:

  1. acccount_id: 11 的文档总数 (3)
  2. acccount_id: 11 AND event 不为空的文档总数 (2)

基本上,我正在寻找的结果是:

{ total: 3, with_event: 2 }

以下是满足上述第二点的代码。它匹配 account_id 和 event 类型 9,这是 Mongo 中的日期时间。如何扩展此代码以满足第 1 点?

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

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

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

    • $matchaccount_id 的条件
    • total, $group by null 和 count 总文档
    • with_event 匹配事件和 $group 为 null 并计数总文档
    • $project 显示必填字段,从构面结果中获取第一个元素
    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] }
        }
      }
    ])
    

    Playground


    第二种方法:

    • $match account_id 的条件
    • $group by null 并获取 total 文档,对于 event 检查条件,如果类型是日期,则计数 1,否则为 0
    mongo.accounts.aggregate([
      { $match: { account_id: 11 } },
      {
        $group: {
          _id: null,
          total: { $sum: 1 },
          with_event: {
            $sum: {
              $cond: [{ $eq: [{ $type: "$event" }, "date"] }, 1, 0]
            }
          }
        }
      }
    ])
    

    Playground

    【讨论】:

    • 谢谢你。你认为哪一个会有更好的表现?
    • 我认为是第二个,你可以通过explain() state 查看性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2011-07-12
    • 2012-01-22
    • 1970-01-01
    • 2021-05-18
    • 2013-03-05
    • 1970-01-01
    相关资源
    最近更新 更多