在展开后将元素重塑为数组

时间:2015-10-27 02:57:47

标签: mongodb mongodb-query aggregation-framework

我有一个看起来像这样的集合

{ name: 'ABC', metadata.tables: [ { name: 'table1' }] }

基本上我想在metadata.tables数组中查询以查找表名称上的elemMatch。我可以通过首先展开metadata.tables数组然后对表名执行$match来使用聚合管道。这工作正常,但现在metadata.tables成为对象而不是数组。这就是查询的样子

db.source.aggregate([ 
 { "$unwind": "$metadata.tables" }, 
 { $match: { "metadata.tables.name": "table 1" } }
])

返回的文档如下所示

{
 "_id": "......",
 "metadata": {
  "tables": {
  }
 }
}

请注意,这些表现在是一个对象而不是一个数组。我理解为什么unwind将它更改为一个对象,但是如何将它恢复为一个包含单个元素的数组(匹配表)。

由于

1 个答案:

答案 0 :(得分:1)

只需使用$group执行$push

db.source.aggregate([ 
 { "$unwind": "$metadata.tables" }, 
 { "$match": { "metadata.tables.name": "table 1" } },
 { "$group": {
     "_id": "$_id",
     "name": { "$first": "$name" },
     "tables": { "$push": "$metadata.tables" }
 }},
 { "$project": {
     "name": 1,
     "metadata": {
         "tables": "$tables"
     }
 }}
])

并且可选地$project,因为聚合累加器不能使用嵌入字段进行输出,您需要重命名,就像显示的那样。

如果您知道自己只是想要或只是想要从每个元素中取出一个元素,那么您可以使用$map {#3}}。文件:

db.source.aggregate([ 
 { "$unwind": "$metadata.tables" }, 
 { "$match": { "metadata.tables.name": "table 1" } },
 { "$project": {
     "name": 1,
     "metadata": {
         "tables": {
             "$map": {
                 "input": ["A"],
                 "as": "el",
                 "in": "$metdata.tables"
             }
         }
     }
 }}
])

这基本上可以替代提供给"输入"的单个元素数组。与该领域的价值。