如何在不知道名称的情况下引用 MongoDB 中的字段?

问题描述 投票:0回答:3

我试图找到MongoDB中某个子文档的所有唯一字符串,只要其中至少一个包含某个子字符串。 但这些字符串是本地化的。 我想获得所有可能语言的结果。

所以,我的文档看起来像这样:

{
  ...
  "myLocalizedField": {
    "en": ...,
    "de": ...,
    "cz": ...
...
}

我不知道数据库中使用哪些语言,并且并非所有文档都使用相同的语言。

这就是我当前的管道:

[
  {
    $match:
      {
        "I DON'T KNOW": {
          $regex: "my substring",
        },
      },
  },
  {
    $project:
      {
        myLocalizedField: 1,
      },
  },
  {
    $unwind:
      {
        path: "$myLocalizedField",
      },
  },
  {
    $group:
      {
        _id: {
          key: "I DON'T KNOW",
        },
      },
  },
]

我不确定在

$match
$group
阶段要放什么...

mongodb mongodb-query aggregation-framework
3个回答
2
投票

您可以使用 $objectToArray 运算符:

伪代码

INPUT:
{"en":"foo", "de":"bar", "cz":"buz"} 
OUTPUT:
[{"k":"en", "v":"foo"}, {"k":"de", "v":"bar"}, {"k":"cz", "v":"buz"}]

db.collection.aggregate([
  {
    "$addFields": {
      "tmp": {
        "$objectToArray": "$myLocalizedField"
      }
    }
  },
  {
    $match: {
      "tmp.v": {
        $regex: "llo"
      }
    }
  },
  {
    $unwind: {
      path: "$tmp"
    }
  },
  {
    $match: {
      "tmp.v": {
        $regex: "llo"
      }
    }
  }
])

Mongo游乐场

注意: 此解决方案无法扩展,因为我们在搜索之前重塑了文档。

我建议您以这种方式存储您的文档:

{
  "myLocalizedField": [
    {"k": "en", "v": "Hello world"},
    {"k": "de", "v": "Hallo Welt"},
    {"k": "cz", "v": "Ahoj světe"},
    {"k": "es", "v": "Hola Mundo"},
  ]
}

通过这种方式,搜索是可扩展的,并且更容易应用过滤器


1
投票

$objectToArray
来救援

[
  {
    $project: { localized: { $objectToArray: "$myLocalizedField" } }
  },
  {
    $unwind:
      {
        path: "$localized",
      },
  },
  {
    $match:
      {
        "localized.v": {
          $regex: "my substring",
        },
      },
  },
  {
    $group:
      {
        _id: {
          key: "$localized.k",
        },
      },
  },
]

0
投票

我推荐这个:

db.collection.aggregate([
   { $set: { myLocalizedField: { $objectToArray: "$myLocalizedField" } } },
   { $match: { "myLocalizedField.v": { $regex: "llo" } } },
   {
      $set: {
         myLocalizedField: {
            $filter: {
               input: "$myLocalizedField",
               cond: { $regexMatch: { input: "$$this.v", regex: "llo" } }
            }
         }
      }
   },
   { $set: { myLocalizedField: { $arrayToObject: "$myLocalizedField" } } }
])

它应该比其他解决方案更快,使用

$unwind
后跟
$group
有点毫无意义。

如您所见,它使用两个正则表达式检查。第一个过滤表达式根本不存在的所有文档,第二个过滤字符串匹配的数组元素。

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.