首页 > 解决方案 > 如何优化聚合查询以根据不同的键进行分组?

问题描述

我的 mongoDB 文档如下所示:

[
  {
    "fields": {
      "field_1": {
        "name": "f1",
        "first": {
          "check": true
        }
      },
      "field_2": {
        "name": "f2",
        "second": {
          "check": true
        }
      },
      "field_3": {},
      "field_4": {
        "name": "f4",
        "second": {
          "check": true
        }
      }
    }
  },
  {
    "fields": {
      "field_1": {
        "name": "f1",
        "second": {
          "check": false
        }
      },
      "field_2": {
        "name": "f2",
        "second": {
          "check": true
        },
        "first": {
          "check": true
        }
      },
      "field_3": {
        "name": "f3",
        "second": {
          "check": true
        }
      }
    }
  }
]

预期输出:

  1. 创建父组 f1( fields.field1.name) 和 f2( fields.field2.name)

  2. 他们每个人都有两个子组,这些子组根据以下条件显示与其父组相关的指标:

    1. first_group:文档数first.check=true
    2. second_group:first.check不存在的文档数量和second.check=true

结果:

[
  {
    "data": [
      {
        "_id": "f1",
        "values": [
          {     
            "second_group": 0,
            "first_group": 1
          }
        ]
      },
      {
        "_id": "f2",
        "values": [
          {
            "second_group": 1,
            "first_group": 1
          }
        ]
      }
    ]
  }
]

我已经使用 $facet 生成了查询,但我不满意,因为我必须在每个父组中重复我的子级分组逻辑(我在 $facet 中有 4 个数组)

我在 Mongo Playground 中的查询附在此处

请告诉我如何删除重复查询。有没有其他方法可以实现这个用例?

谢谢!

标签: mongodbmongodb-queryaggregation-frameworkgroupingaggregation

解决方案


发布适用于给定条件和预期 O/p 的聚合查询:

db.collection.aggregate([
  {
    $unwind: "$fields",
  },
  {
    $project: {
      data: {
        $objectToArray: "$fields",
      },
    },
  },
  {
    $unwind: "$data",
  },
  {
    $match: {
      "data.v.first.check": true,
    },
  },
  {
    $group: {
      _id: "$data.v.name",
      values: {
        $push: {
          first_group: {
            $sum: {
              $cond: [
                {
                  $eq: ["$data.v.first.check", true],
                },
                1,
                0,
              ],
            },
          },
          second_group: {
            $sum: {
              $cond: [
                {
                  $eq: ["$data.v.second.check", true],
                },
                1,
                0,
              ],
            },
          },
        },
      },
    },
  },
]);

播放链接


推荐阅读