MongoDB聚合按查询分组

时间:2020-05-12 20:42:05

标签: mongodb mongodb-query aggregation-framework

我有一个mongoDB集合,我想做一个聚合查询。
我正在按alert_type字段分组,但我也希望将这些alert_type的列表作为输出中的单独字段。

收藏集如下:

db.test.insertMany([
  {
    "output_data": {
      "alert_type": "UAlert",
      "overallImpact": {
        "margin": 0.1,
        "workingCapital": 3.33
      }
    }
  },
  {
    "output_data": {
      "alert_type": "CAlert",
      "overallImpact": {
        "margin": 0.1,
        "workingCapital": 3.33
      }
    }
  },
  {
    "output_data": {
      "alert_type": "UAlert",
      "overallImpact": {
        "margin": 0.1,
        "workingCapital": 3.33
      }
    }
  }
])

我尝试过的查询

db.test.aggregate([
  {$group: {
      "_id": "$output_data.alert_type",
      "alert_type": {
        "$first": "$output_data.alert_type"
      },
      "margin": {
        "$sum": "$output_data.overallImpact.margin"
      },
      "workingCapital": {
        "$sum": "$output_data.overallImpact.workingCapital"
      },
      "alert_types": {
        "$addToSet": "$output_data.alert_type"
      }
    }
  },
  {$project: {'_id': 0
    }
  }
])

当前输出

{
  "alert_type": "UAlert",
  "margin": 0.2,
  "workingCapital": 6.66,
  "alert_types": [
    "UAlert"
  ]
}
{
  "alert_type": "CAlert",
  "margin": 0.1,
  "workingCapital": 3.33,
  "alert_types": [
    "CAlert"
  ]
}

必需的输出

{
  "data": [
    {
      "alert_type": "UAlert",
      "margin": 0.2,
      "workingCapital": 6.66,
    },
    {
      "alert_type": "CAlert",
      "margin": 0.1,
      "workingCapital": 3.33,
    }
  ],
  "alert_types": [
    "UAlert",
    "CAlert"
  ]
}

有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

您必须使用$facet来实现此目的,在一个阶段中,您需要进行分组以获取数据,而在另一个阶段中,您将找到所有可用的警报类型。

db.collection.aggregate([
  {
    $facet: {
      data: [
        {
          $group: {
            "_id": "$output_data.alert_type",
            "alert_type": {
              "$first": "$output_data.alert_type"
            },
            "margin": {
              "$sum": "$output_data.overallImpact.margin"
            },
            "workingCapital": {
              "$sum": "$output_data.overallImpact.workingCapital"
            },
          }
        },
        {
          $project: {
            "_id": 0
          }
        }
      ],
      "alert_types": [
        {
          $group: {
            _id: null,
            "names": {
              "$addToSet": "$output_data.alert_type"
            }
          }
        }
      ]
    }
  },
  {
    $project: {
      data: 1,
      alert_types: "$alert_types.names"
    }
  }
]) 

您可以here对其进行测试

答案 1 :(得分:1)

您可以尝试以下聚合查询:

db.collection.aggregate([
    {
      $group: {
        "_id": "$output_data.alert_type",
        alert_type: { $first: "$output_data.alert_type" },
        margin: { $sum: "$output_data.overallImpact.margin" },
        workingCapital: { $sum: "$output_data.overallImpact.workingCapital" }
      }
    },
    /** Optional stage - Just to exclude `_id` inside each object of data array from final output */
    {
      $project: { _id: 0 }
    },
    /** Grouping on all docs, For this group stage we will have lesser docs compared to prior Group stage */
    {
      $group: {
        _id: "", // Group without any condition
        data: {  $push: "$$ROOT" }, // Pushing all docs into an array
        alert_types: { $addToSet: "$alert_type" } // Adding unique values
      }
    },
    /** Optional stage - Just to exclude `_id` final output doc */
    {
      $project: { _id: 0 }
    }
  ])

测试: mongoplayground