展开后将元素重塑为数组

阿德玛哈穆德

我有一个看起来像这样的收藏

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

基本上,我想在metadata.tables数组中查询以在表名上查找elemMatch。我可以使用聚合管道来做到这一点,方法是先展开metadata.tables数组,然后再执行$matchon表名。这可以正常工作,但是现在它metadata.tables变成了对象而不是数组。这就是查询的样子

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

返回的文档如下所示

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

注意,表现在是对象而不是数组。我知道为什么展开将其更改为对象,但是如何将其还原为其中包含单个元素的数组(匹配表)。

谢谢

布雷克七世

只需执行$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如果您知道每个“未展开”文档中只有一个元素或只想要一个元素,则可以使用

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"
             }
         }
     }
 }}
])

这实际上将用字段的值替换提供给“输入”的单个元素数组。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章