MongoDB投影和字段子集 [英] MongoDB projections and fields subset
问题描述
我想使用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.
问题:
- 有可能吗?
- 我怎样才能做到这一点。 $ elemMatch似乎没有帮助我。我正在尝试放松,但没有到达那里
- 如果可能的话,这个投影过滤是否可以从
user.some_list.x上的索引中受益
例如?或者一旦用户已被其ID识别,一点都没有?
- Is it possible?
- How can I achieve this. $elemMatch doesn't seem to help me. I'm trying something with unwind, but not getting there
- 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屋!