具有嵌套对象数组的 MongoDB 组聚合

MongoDB group aggregate with nested array of objects

提问人:DAVI FONSECA 提问时间:11/9/2023 更新时间:11/15/2023 访问量:36

问:

我有一个具有以下结构的集合(我将发布一个指向 playground 的链接,因为它非常大):

https://mongoplayground.net/p/WNga0mze0WS

简单解释一下,我们正在寻找(主题)和(主题),我们希望该聚合返回一个数组(该主题的名称),该数组的(错误)是(正确)的 3 倍或更多,以便我们可以显示学生需要改进的主题。其他结果无关紧要,只有当它是 3 倍或更多时。materiasassuntosnomeserrosacertos

我想做一个聚合来对 进行分组,因为在这个集合上,你可以从另一个用户那里获得结果,并尝试根据主题名称()添加所有错误和正确答案。user.uidassuntos.nome

到目前为止,我已经尝试了很多东西,但这是我尝试过的最后一件事:

db.aggregate([
          { $unwind: "$materias" },
          { $unwind: "$materias.assuntos" },
          {
            $group: {
              _id: {
                _id: "$user.uid",
                nome: "$materias.assuntos.nome",
                total: "$materias.assuntos.total",
                acertos: "$materias.assuntos.acertos",
                erros: "$materias.assuntos.erros",
                // sumErro: {
                //   $sum: {
                //     "$toInt": "$materias.assuntos.erros"
                //   }
                // },
                teste: {
                  // $sum: {
                  "$cond": {
                    "if": {
                      "$and": [
                        {
                          "$gte": [
                            "$materias.assuntos.erros", 3
                          ]
                        },
                        {
                          "$gte": [
                            "$materias.assuntos.erros",
                            { $multiply: [ "$materias.assuntos.acertos", 3 ] }
                          ]
                        }
                      ]
                    },
                    "then": "$materias.assuntos.erros",
                    "else": "$$REMOVE",
                  }
                  // }
                }
              },
            },
          },
          {
            $group: {
              _id: {
                _id: "$_id._id",
                nome: "$_id.nome",
                erros: "$_id.erros",
                teste: "$_id.teste"
              },
            }
          }
        ])

我还尝试仅按 uid 和 materias.assuntos.nome 进行分组,然后进行分组以获得结果,但无法成功。我在那里做的条件是,我正在寻找的 erros 比 acertos 多 3 倍,我认为 erros 也需要 3 个或更多。

我期望一个结果至少有 3 个以上的错误,但我做错了什么,因为它没有根据主题的名称添加这些值。

如果需要,我还可以提供另一份文档,因为我发送的文档只有 1 个主题,其错误是 acertos 的 3 倍。

任何帮助将不胜感激

数组 mongoDB 多维数组 聚合框架 聚合

评论


答:

1赞 Alexandre Akira 11/15/2023 #1

通过在操场上工作,我得到了这种解决方案

db.collection.aggregate([
  {
    $unwind: "$materias"
  },
  {
    $unwind: "$materias.assuntos"
  },
  {
    $group: {
      _id: {
        user: "$user.uid",
        nomeAssunto: "$materias.assuntos.nome"
      },
      total: {
        $sum: "$materias.assuntos.total"
      },
      acertos: {
        $sum: "$materias.assuntos.acertos"
      },
      erros: {
        $sum: "$materias.assuntos.erros"
      }
    }
  },
  {
    $group: {
      _id: "$_id.user",
      assuntos: {
        $push: {
          nome: "$_id.nomeAssunto",
          total: "$total",
          acertos: "$acertos",
          erros: "$erros"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      user: "$_id",
      assuntos: {
        $filter: {
          input: "$assuntos",
          as: "assunto",
          cond: {
            "$and": [
              {
                $gte: [
                  "$$assunto.erros",
                  3
                ]
              },
              {
                $lte: [
                  {
                    $multiply: [
                      "$$assunto.acertos",
                      3
                    ]
                  },
                  "$$assunto.erros"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    "$match": {
      assuntos: {
        "$exists": true,
        "$not": {
          "$size": 0
        }
      }
    }
  }
])