【问题标题】:MongoDB - Group Across Two Fields & Then Group On Remaining Third FieldMongoDB - 跨两个字段分组,然后在剩余的第三个字段上分组
【发布时间】:2022-01-13 21:00:50
【问题描述】:

我正在使用 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 重新处理数据,但无法将上面的内容更接近(我通常会抛出内部服务器错误)。

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

【问题讨论】:

  • 用于对事物进行分组的字段顺序。系列+品牌和品牌+系列是不同的。

标签: mongodb mongoose aggregation-framework


【解决方案1】:

问题是你按所有字段分组,正确如下,

  • $group by seriesbrandmodel 字段并取平均值
  • $group by seriesbrand 字段并使用 model 和平均字段构造 data 数组
  • $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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    相关资源
    最近更新 更多