MongoDB - 对两个字段进行分组,然后对剩余的第三个字段进行分组

MongoDB - Group Across Two Fields & Then Group On Remaining Third Field

我正在使用 MongoDB(通过带有 NodeJS/Express 后端的 Mongoose)并且有一个数据结构,我首先需要按两个字段分组,然后在该级别分组,然后分组通过数据库中的第三个字段。

我的数据结构如下(为简单起见删减):

{
{
   brand: "AMD",
   series: "5000",
   model: "5900x",
   userRating: 5
},
{
   brand: "AMD",
   series: "5000",
   model: "5900x",
   userRating: 2
},
{
   brand: "AMD",
   series: "5000",
   model: "5600x",
   userRating: 3
},
{
   brand: "AMD",
   series: "3000",
   model: "3900x",
   userRating: 5
},
{
   brand: "Intel",
   series: "i9",
   model: "12900k",
   userRating: 5
},
{
   brand: "Intel",
   series: "i9",
   model: "12900k",
   userRating: 4
}
}

您会注意到,单个 CPU 模型可以重复多次。

因此,我正在尝试做的事情如下:

  1. brandseries

    分组
  2. 一旦按 brandseries 分组,然后在个体 model 级别分组并平均该模型的 userRating

所以最终想要的数据结果如下

{
{
   brand: "AMD",
   series: "5000",
   data: [
      {
       model: "5900x"
       avgRating: 3.5
      },
      {
      model: "5600x"
       avgRating: 3
      }      
      ]
},
{
   brand: "AMD",
   series: "3000",
   data: [
      {
       model: "3900x"
       avgRating: 5
      } 
      ]
},
{
   brand: "Intel",
   series: "i9",
   data: [
      {
       model: "12900k"
       avgRating: 4.5
      } 
      ]
}

}

我已经尝试了 100 种方法和一种方法来尝试让它工作,但我仍然感到困惑。

我花了 2 晚的时间才看到最近的结果如下:

const aggregate = await CpuReviews.aggregate([
      {
        $group: {
          _id: {
            groupId: { series: "$series", brand: "$brand" },
            model: "$model",
            userRating: { $avg: "$userRating" },
          },
        },
      },
      {
        $group: {
          _id: "$_id.groupId",
          data: {
            $push: {
              model: "$_id.model",
              userRating: { $avg: "$_id.userRating" },
            },
          },
        },
      },
    ]);

最终的数据结构如下:

{
        "_id": {
            "series": "3000",
            "brand": "amd"
        },
        "data": [
            {
                "model": "Ryzen 9 3950X",
                "userRating": 5678
            }
        ]
    },

我也尝试过使用 $project 来重新处理数据,但无法利用上面的内容并使其更接近(我通常会抛出内部服务器错误)。

提前感谢您提供任何有关我哪里出错以及如何回到正确路径的见解。

问题是您已按所有字段分组,更正如下,

  • $group 通过 seriesbrandmodel 字段并得到平均值
  • $groupseriesbrand 字段构建 data 数组 model 和平均字段
  • $project 显示必填字段并格式化结果
const aggregate = await CpuReviews.aggregate([
  {
    $group: {
      _id: {
        series: "$series",
        brand: "$brand",
        model: "$model"
      },
      avgRating: { $avg: "$userRating" }
    }
  },
  {
    $group: {
      _id: {
        series: "$_id.series",
        brand: "$_id.brand"
      },
      data: {
        $push: {
          model: "$_id.model",
          avgRating: "$avgRating"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      series: "$_id.series",
      brand: "$_id.brand",
      data: 1
    }
  }
])

Playground