【发布时间】:2017-03-15 23:35:43
【问题描述】:
我收集了一个包含以下文档的集合:
{
"_id": 0,
"pictures": [
{
"path": "/path/to/first/picture.jpg",
"web": "true"
},
{
"path": "/path/to/second/picture.jpg",
"web": "true",
}
],
"logos": [
{
"path": "/path/to/first/logo.jpg",
"web": "true"
},
{
"path": "/path/to/second/logo.jpg",
"web": "false",
}
]
}
{
"_id": 1,
"pictures": [
{
"path": "/a/bit/weird/path/to/picture.jpg",
"web": "false"
},
{
"path": "/another/weird/path/to/picture.jpg",
"web": "false",
}
],
"logos": [
{
"path": "/path/to/another/logo.jpg",
"web": "false"
},
{
"path": "/a/last/path/to/logo.jpg",
"web": "true",
}
]
}
我想要得到的结果是符合以下条件的这个。
{
"web_images": [
{
"path": "/path/to/first/picture.jpg",
"web": "true"
},
{
"path": "/path/to/second/picture.jpg",
"web": "true",
},
{
"path": "/path/to/first/logo.jpg",
"web": "true"
},
{
"path": "/a/last/path/to/logo.jpg",
"web": "true",
}
]
}
唯一真正的条件是获取所有路径,这些路径的“web”字段中的字符串设置为 true。 (我知道它也可能是布尔值,但在这种情况下没关系) 主要问题是将数组“logos”和“pictures”合并为一个数组。 我使用“$unwind”阅读了一些解决方案。但在这些情况下,他们试图连接一个数组。
这对我有用,但在我的真实案例中,我得到了五个包含这些对象的不同数组。他们必须把所有结果都放在一个数组中。
到目前为止,我的解决方案如下(但不起作用):
db.products.aggregate( [
{ $unwind: "$pictures" },
{ $unwind: "$logos" },
{ $group: { _id: null, pics: { $push: { $or: ["$pictures", "$logos"] } } } }
{ $project: { _id: 0, pictures: "$pics" } }
] );
如您所见,仍然缺少对“web”标志的条件检查。输出也绝对没有带来任何东西。甚至没有错误消息。
编辑
我忘记了这个问题的一个重要细节。
正如我在上半部分所述,每个文档中可以出现五个不同的数组。也有可能每个文档中都没有它们。所以它也可以是这样的:
{
"_id": 1,
"pictures": [
{
"path": "/a/bit/weird/path/to/picture.jpg",
"web": "false"
},
{
"path": "/another/weird/path/to/picture.jpg",
"web": "false",
}
]
}
这可能是我的问题与已解决的问题之间的区别,我的问题被标记为重复。正如@Styvane 告诉我的那样,它给了我大量的文件,例如:
{
"_id" : ObjectId("57f5026aaf39013d0c9186af"),
"web_images": null
}
我可能会因为那些缺少某些数组的文档而收到此错误。
【问题讨论】:
-
对于条件,只需将
$setUnion表达式包装在$filter中:db.collection.aggregate([{"$project": { "web_images": { "$filter": { "input": { "$setUnion": [ "$pictures", "$logos" ] }, "as": "p", "cond": { "$eq": [ "$$p.web", "true" ] } } } } }]) -
"$eq": [ "$$p.web", "true"] 中的 $$ 有什么作用?它对我不起作用。我只得到了数千个带有 id 和“web_images”的文档:null
-
p是 concatenated 数组中每个元素的变量名。要访问cond表达式中的该变量,MongoDB 要求您在其前面加上$$并使用“点符号”来访问子文档字段。希望我回答了你的问题。 -
是的,谢谢你,但它仍然不想在一个文档中给我我的结果。我仍然得到大量无用的文件。 { "_id": ObjectId("someHash"), "web_images": null }
-
糟糕,我可能忘记了一个重要细节:文档也可能不包含一个或两个字段。它可能只包含“图片”,只包含“徽标”,甚至两者都不包含。这会是个大问题吗?
标签: javascript mongodb mongodb-query aggregation-framework