我有一个看起来像这样的集合
{ 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将它更改为一个对象,但是如何将它恢复为一个包含单个元素的数组(匹配表)。
由于
答案 0 :(得分:1)
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"
}
}
}
}}
])
这基本上可以替代提供给"输入"的单个元素数组。与该领域的价值。