MongoDB投影和字段子集 [英] MongoDB projections and fields subset

查看:188
本文介绍了MongoDB投影和字段子集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to use mongo projections in order to return less data to my application. I would like to know if it's possible.

示例:

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 = 1 user.other_list.x = 1 是否可以达到给定的结果?

Given a query for user_id = 123 and some 'projection filter' like user.some_list.x = 1 and user.other_list.x = 1 is it possible to achieve the given result?

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

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

The ideia is to make mongo work a little more and retrieve less data to the application. In some cases, we are discarding 80% of the elements of the collections at the application's side. So, it would be better not returning then at all.

问题:


  1. 有可能吗?

  2. 我怎样才能做到这一点。 $ elemMatch似乎没有帮助我。我正在尝试放松,但没有到达那里

  3. 如果可能的话,这个投影过滤是否可以从 user.some_list.x上的索引中受益例如?或者一旦用户已被其ID识别,一点都没有?

  1. Is it possible?
  2. How can I achieve this. $elemMatch doesn't seem to help me. I'm trying something with unwind, but not getting there
  3. If it's possible, can this projection filtering benefit from a index on user.some_list.x for example? Or not at all once the user was already found by its id?

谢谢。

推荐答案

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

What you can do in MongoDB v3.0 is this:

db.collection.aggregate({
    $match: {
        "user.id": 123
    }
}, {
    $redact: {
        $cond: {
             if: {
                 $or: [ // those are the conditions for when to include a (sub-)document
                     "$user", // if it contains a "user" field (as is the case when we're on the top level
                     "$some_list", // if it contains a "some_list" field (would be the case for the "user" sub-document)
                     "$other_list", // the same here for the "other_list" field
                     { $eq: [ "$x", 1 ] } // and lastly, when we're looking at the innermost sub-documents, we only want to include items where "x" is equal to 1
                 ] 
             },
             then: "$$DESCEND", // descend into sub-document
             else: "$$PRUNE" // drop sub-document
        }
    }
})

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

Depending on your data setup what you could also do to simplify this query a little is to say: Include everything that does not have a "x" field or if it is present that it needs to be equal to 1 like so:

$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
    }
}

您建议的索引不会对 $ redact执行任何操作阶段。但是,如果您更改 $ match 开始阶段摆脱所有不匹配的文件,如下:

The index you suggested won't do anything for the $redact stage. You can benefit from it, however, if you change the $match stage at the start to get rid of all documents which don't match anyway like so:

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

这篇关于MongoDB投影和字段子集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆