使用投影进行Mongo查询

时间:2016-10-16 03:19:42

标签: mongodb mongodb-query pymongo

在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"}

匹配的dict元素

谢谢

3 个答案:

答案 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

的情况下工作