能否将MongoDB查询结果扁平化?

72

我在MongoDB集合中有一个深度嵌套的集合。

当我运行以下查询时:

db.countries.findOne({},{'data.country.neighbor.name':1,'_id':0})

我最终得到了这个嵌套的结果:

{"data" : {
  "country" : [
    {
      "neighbor" : [
        {
          "name" : "Austria"
        },
        {
          "name" : "Switzerland"
        }
      ]
    },
    {
      "neighbor" : {
        "name" : "Malaysia"
      }
    },
    {
      "neighbor" : [
        {
          "name" : "Costa Rica"
        },
        {
          "name" : "Colombia"
        }
      ]
    }
  ]
}}

现在,这就是我想要的:

['Austria', 'Switzerland', 'Malaysia', 'Costa Rica', 'Colombia']

或者这个:

{'name':['Austria', 'Switzerland', 'Malaysia', 'Costa Rica', 'Colombia']}

或者任何类似的东西...这种情况可能吗?

4个回答

91
你可以使用聚合框架中的 $project$unwind$group 来使结果更接近你的要求。 aggregation
> db.countries.aggregate({$project:{a:'$data.country.neighbor.name'}},
                         {$unwind:'$a'},
                         {$unwind:'$a'},
                         {$group:{_id:'a',res:{$addToSet:'$a'}}})
  {
    "result" : [
        {
            "_id" : "a",
            "res" : [
                "Colombia",
                "Malaysia",
                "Switzerland",
                "Costa Rica",
                "Austria"
            ]
        }
    ],
    "ok" : 1
}

$unwind被使用两次,因为名称数组嵌套较深。 只有当neighbor属性是一个数组时,它才有效。在您的示例中,一个邻居字段(马来西亚)不是一个数组。


谢谢!我得到了以下的结果:{ "result" : [ ], "ok" : 1 } :/ - Marsellus Wallace
有趣。虽然感觉还有很多工作要做,但我想我只能逐渐习惯了。谢谢。 - Marsellus Wallace
11
五年后看到这个...Mongo - 我很喜欢它 - 仍然特别奇怪。 - The Dembinski

13

用更简单的方式完成它,也许这是最近的事情

db.countries.aggregate({$unwind:'$data.country.neighbor.name'})

2
为了扁平化您的数据,您也可以使用$reduce。这里是文档中的一个示例:链接
db.countries.aggregate([
  {
    $addFields: {
      newField: {
        $reduce: {
          input: "$data.country.neighbor.name",
          initialValue: [],
          in: { $concatArrays: ["$$value", "$$this"] }
        }
      }
    }
  }
])

-7

在新的聚合框架下,这非常简单。$project和$unwind操作正好符合要求。


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