【问题标题】:Mongo query with projection带有投影的 Mongo 查询
【发布时间】:2016-10-17 21:48:34
【问题描述】:

在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元素

谢谢

【问题讨论】:

  • 当你添加一个空白对象作为第一个参数时会发生什么:db.resource.find({}, {packages: {"$elemMatch": {installed_date: "2016-08-03"} }})
  • 看起来不工作,它返回所有其他没有那个日期的包。

标签: mongodb mongodb-query pymongo


【解决方案1】:

尝试 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'}}}
])

【讨论】:

    【解决方案2】:

    对于不使用 $unwind 运算符的解决方案,请考虑在 $setDifference 旁边使用 $map,这样您可以“过滤”数组内容。

    这更有效,因为它在单个 $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" 的元素。

    【讨论】:

      【解决方案3】:

      尝试以下查询:它将适用于 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 的情况下工作

      【讨论】:

      • 谢谢,等我升级到 3.2 试试看
      • 太棒了,如果可能的话,升级到 3.2。有很多新东西和更好的性能。见slideshare.net/chenghanTsai1/…
      猜你喜欢
      • 1970-01-01
      • 2014-05-11
      • 2020-10-02
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多