8

我发现 MongoDB 聚合框架非常强大——它似乎是展平对象的好选择。我的架构在一个名为materials. 数量materials是可变的,但特定字段category在数组中的对象中是唯一的。我想使用聚合框架来展平结构并根据字段的值动态重命名category字段。我找不到一种简单的方法来使用 a$project$cond. 有办法吗?

物质对象数组的原因是允许简单的搜索:

例如{ 'materials.name' : 'XYZ' },拉回找到“XYZ”的任何文档。

例如之前和之后的文件

{
"_id" : ObjectId("123456"),
"materials" : [
    {
        "name" : "XYZ",
        "type" : "Red",
        ...
        "category" : "A"
    },
    {
        "name" : "ZYX",
        "type" : "Blue",
        ...
        "category" : "B"
    }]
}

{
"material_A_name" : "XYZ",
"material_A_type" : "Red",
...
"material_B_name" : "ZYX",
"material_B_type" : "Blue",
...
}
4

2 回答 2

6

在 jira https://jira.mongodb.org/browse/SERVER-5947中有这样的请求- 如果您想拥有此功能,请投票。

同时,如果您事先知道键的可能值是什么(即“类别”的所有唯一值),并且我在我的博客上有一些示例代码,则有一种解决方法。

于 2013-09-01T20:46:28.063 回答
3

这对 MongoDB v4.4 很有用,

  • $mapmaterials迭代数组的循环
  • $map使用转换为数组后迭代name和字段的循环,根据字段和值使用连接您的关键字段要求,type$objectToArray$concat
  • 返回第一个$map将返回的结果从第二个$map数组转换为对象使用$arrayToObject
  • $unwind解构materials数组
  • $group通过 null 并将materials对象合并到一个对象
  • $replaceRoot替换根中的对象
db.collection.aggregate([
  {
    $project: {
      materials: {
        $map: {
          input: "$materials",
          as: "m",
          in: {
            $arrayToObject: [
              {
                $map: {
                  input: {
                    $objectToArray: {
                      name: "$$m.name",
                      type: "$$m.type"
                    }
                  },
                  in: {
                    k: { $concat: ["material", "_", "$$m.category", "_", "$$this.k"] },
                    v: "$$this.v"
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { $unwind: "$materials" },
  {
    $group: {
      _id: null,
      materials: { $mergeObjects: "$materials" }
    }
  },
  { $replaceRoot: { newRoot: "$materials" } }
])

操场

于 2020-12-11T06:17:39.553 回答