MongoDB聚合框架 - 动态字段重命名

8
我发现MongoDB聚合框架非常强大 - 它似乎是将对象展平的好选择。我的模式在一个名为materials的数组中使用子对象的数组。 materials的数量是可变的,但特定字段category将在数组中的对象中唯一。我想使用聚合框架来展开结构并根据category字段的值动态重命名字段。我无法找到一种使用$project$cond轻松完成此任务的方法。是否有一种方法?
物料对象的数组的原因是允许简单搜索:
例如:{'materials.name':'XYZ'}会拉回任何包含“XYZ”的文档。
之前和之后文档的示例:
{
"_id" : ObjectId("123456"),
"materials" : [
    {
        "name" : "XYZ",
        "type" : "Red",
        ...
        "category" : "A"
    },
    {
        "name" : "ZYX",
        "type" : "Blue",
        ...
        "category" : "B"
    }]
}

to

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

你的“after”文档不是有效的JSON。 - JohnnyHK
谢谢,已更新 - 这是我在编辑器中创建模拟的错误。 - user2234151
好的,我现在明白你想做什么了。聚合框架中对于动态生成键的支持不是很好,所以我不认为你可以用它来实现这个。你可能需要在代码中进行后处理来完成它。 - JohnnyHK
感谢您的关注。我现在在Python代码中进行后处理,但我正在寻找一种优雅/优雅的方式来创建一个API,以便从另一个应用程序查询Mongo,并查询以表格形式查看数据。例如,该API将获取连接详细信息和聚合JSON字符串管道,以生成扁平化结果以生成表格报告。 - user2234151
2个回答

6

在jira中有一个类似这样的请求 https://jira.mongodb.org/browse/SERVER-5947 - 如果你想要这个功能,请投票支持。

同时,如果你预先知道键的可能值(即“category”的所有唯一值),则可以使用一个解决方法,并且我在我的博客上提供了一些示例代码(链接)


请注意,自MongoDB 3.4.4版本以来,可以将键转置为值,反之亦然。 - Asya Kamsky

3

从MongoDB v4.4开始,以下操作将非常有用:

  • $map 迭代 materials 数组的循环
  • $map 迭代 nametype 字段的循环,在使用 $objectToArray 将其转换为数组后,根据字段和值要求连接您的键字段,使用 $concat
  • 返回到第一个 $map,使用 $arrayToObject 将第二个 $map 返回的结果从数组转换为对象
  • $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" } }
])

游乐场

(涉及IT技术)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接