我想使用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 = 1
和user.other_list.x = 1
那样可以达到给定的结果吗?
user: {
id: 123,
some_list: [{x:1, y:2}],
other_list: []
}
ideia是让mongo工作更多一点,并为应用程序检索更少的数据。在某些情况下,我们在应用程序方面丢弃了80%的集合元素。所以,最好不要再回来了。
问题:
user.some_list.x
上的索引中受益?或者,一旦用户已经被其ID找到,就完全没有了?谢谢。
答案 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 ]}
}}
}}
]);