MongoDB投影和字段子集

时间:2017-10-12 23:44:22

标签: mongodb indexing mongodb-query filtering projection

我想使用mongo投影,以便将更少的数据返回给我的应用程序。我想知道它是否可能。

示例:

user: {
  id: 123,
  some_list: [{x:1, y:2}, {x:3, y:4}],
  other_list: [{x:5, y:2}, {x:3, y:4}]
}

鉴于对user_id = 123和某些'投影过滤器的查询'像user.some_list.x = 1user.other_list.x = 1那样可以达到给定的结果吗?

user: {
  id: 123,
  some_list: [{x:1, y:2}],
  other_list: []
}

ideia是让mongo工作更多一点,并为应用程序检索更少的数据。在某些情况下,我们在应用程序方面丢弃了80%的集合元素。所以,最好不要再回来了。

问题:

  1. 有可能吗?
  2. 我怎样才能做到这一点。 $ elemMatch似乎没有帮助我。我尝试放松,但没有到达那里
  3. 如果可能,此投影过滤是否可以从user.some_list.x上的索引中受益?或者,一旦用户已经被其ID找到,就完全没有了?
  4. 谢谢。

3 个答案:

答案 0 :(得分:1)

您在MongoDB v3.0中可以做的是:

$redact: {
    $cond: {
         if: {
             $eq: [ { "$ifNull": [ "$x", 1 ] }, 1 ] // we only want to include items where "x" is equal to 1 or where "x" does not exist
         },
         then: "$$DESCEND", // descend into sub-document
         else: "$$PRUNE" // drop sub-document
    }
}

根据您的数据设置,您还可以采取哪些措施来简化此查询,可以说:包含所有没有" x"字段或如果它存在,它需要等于1,如下:

$match: {
    "user.id": 123,
    "user.some_list.x": 1 // this will use your index
}

您建议的索引不会为$redact阶段做任何事情。但是,如果您在开始时更改$match阶段以摆脱所有不匹配的文档,您可以从中受益:

'chromeOptions': {'args': ['lang=en-GB',  'enable-precise-memory-info' , 'js-flags=--expose-gc', 'no-sandbox']}

答案 1 :(得分:0)

非常可能。

使用findOne,查询是第一个参数,投影是第二个参数。在Node / Javascript中(类似于bash):

db.collections('users').findOne( { 
    id = 123 
}, {
    other_list: 0
} )

将返回没有other_list字段的who' ll对象。或者您可以指定{ some_list: 1 }作为投影,并且只返回_id和some_list

答案 2 :(得分:0)

$filter是你的朋友。下面产生你寻求的输出。尝试更改$eq字段和目标值,以查看数组中更多或更少的项目。请注意我们如何$project新字段(some_list和other_list)“在旧字段之上”,基本上用过滤后的版本替换它们。

db.foo.aggregate([
{$match: {"user.id": 123}}
,{$project: { "user.some_list": { $filter: {
            input: "$user.some_list",
            as: "z",
            cond: {$eq: [ "$$z.x", 1 ]}
        }},
          "user.other_list": { $filter: {
    input: "$user.other_list",
            as: "z",
            cond: {$eq: [ "$$z.x", 1 ]}
              }}
}}
                ]);