首页 > 解决方案 > mongo db 聚合中 $set 的动态字段路径

问题描述

我有包含多语言数据的文档。简化版本如下所示:

  {
    languages: [
      "en",
      "fr"
    ],
    title: {
      en: "Potato Gratin",
      fr: "Gratin de pomme de terre"
    },    
  }

重要的部分是:

我想做的是查询该文档以获取特定语言,或者

即用法语查询上述文档应该返回{"title": "Gratin de pomme de terre"},如果用中文查询,它应该返回{"title": "Potato Gratin"}

我有一个游乐场设置:https ://mongoplayground.net/p/CP0Z20dTpgy 。我有它,以便它设置lang输出应该在其中的属性。然后我想要一个看起来像"$set": {"title": "$title.$lang"}但它抱怨字段路径组件不应该以开头的阶段$,我猜这意味着 mongo 不支持动态字段路径?

关于如何实现这样的目标的任何想法?

一些注意事项:

标签: mongodbmongodb-queryaggregation-framework

解决方案


您必须使用 $objectToArray 将对象转换为数组,过滤此数组并获取其中的元素 0。然后你可以改变你的价值。

db.collection.aggregate([
  {
    "$match": {
      "_id": BinData(0, "3BByrilZQ2GTdlXG0nrGXw=="),
      
    },
  },
  {
    "$set": {
      "lang": {
        "$cond": [
          {
            "$in": [
              "zh",
              "$languages"
            ]
          },
          "zh",
          {
            "$first": "$languages"
          }
        ]
      }
    }
  },
  {
    $addFields: {
      title: {
        "$arrayElemAt": [
          {
            "$filter": {
              "input": {
                "$objectToArray": "$title"
              },
              "as": "title",
              "cond": {
                $eq: [
                  "$$title.k",
                  "$lang"
                ]
              }
            }
          },
          0
        ]
      }
    }
  },
  {
    $addFields: {
      title: "$title.v"
    }
  }
])

当然,您必须在两个地方都将您的“zh”作为参数传递给您的代码。

你可以在这里测试


推荐阅读