在mongo中如果条件匹配,如何从列表中返回所有匹配dict元素。
这是我的数据:
{"packages": [
{"package_name" : "abc", "installed_date" : "2016-08-03"},
{"package_name" : "def", "installed_date" : "2016-08-04"},
{"package_name" : "ghi", "installed_date" : "2016-08-03"},
]
}
如何查询以获取与{"installed_date" : "2016-08-03"}
我试过了:
db.resource.find({packages: {"$elemMatch": {installed_date: "2016-08-03"}}})
但是这给了我所有的数组元素。我想获得与{installed_date: "2016-08-03"}
谢谢
答案 0 :(得分:5)
尝试mongo聚合:
db.resource.aggregate([
{'$match':{'packages.installed_date':'2016-08-03'}},
{'$unwind':'$packages'},
{'$match':{'packages.installed_date':'2016-08-03'}},
{'$group':{'_id':'$_id', 'packages':{'$push':'$packages'}}}
])
答案 1 :(得分:2)
对于不使用 $unwind
运算符的解决方案,请考虑使用 $map
以及 $setDifference
,您可以“过滤”数组内容。
这更有效率,因为它在单个 $project
管道中运行,并且 $unwind
生成文档的笛卡尔积,即副本每个数组条目的每个文档的数量,它使用更多的内存(聚合管道上可能的内存上限为10%总内存),因此在展平过程中生成以及处理文档需要时间:
db.resource.aggregate([
{
"$project": {
"packages": {
"$setDifference": [
{
"$map": {
"input": "$packages",
"as": "item",
"in": {
"$cond": [
{ "$eq": [ "$$item.installed_date", "2016-08-03" ] },
"$$item",
false
]
}
}
},
[false]
]
}
}
}
])
在上面的管道中, $map
运算符本质上创建了一个新的数组字段,该字段通过子表达式中对数组的每个元素的计算逻辑来保存值。
然后 $setDifference
运算符返回一个集合,其中的元素出现在第一个集合中但不出现在第二个集合中;即执行第二组相对于第一组的相对补码。在这种情况下,它将返回包含packages
元素的最终installed_date = "2016-08-03"
数组。
答案 2 :(得分:1)
尝试以下查询:它适用于mongodb 3.2
db.resource.aggregate([
{$match:{"packages.installed_date" : "2016-08-03"}},
{ $project: {
package: {$filter: {
input: '$packages',
as: 'package',
cond: {$eq: ['$$package.installed_date', "2016-08-03"]}
}}
}}
])
这将在没有多重匹配条件和$ unwind
的情况下工作