如果值与巨大的子数组中的值匹配,是否有直接的方法来投影新字段。我知道我可以在$ match条件中使用$ elemMatch或$,但这不允许我获得其余的非匹配值(在我的情况下是用户)。
基本上我想列出所有类型1项目并在突出显示订阅用户时显示所有用户。我想通过mongodb这样做的原因是为了避免为每个项目迭代超过数千个用户。事实上,这是我的问题的第2部分,我可以限制将返回的用户数组的数量,我只需要返回大约10个数组值而不是数千个。
集合结构是
{
name: "Coke",
type: 2,
users:[{user: 13, type:1},{ user:2: type:2}]
},
{
name: "Adidas",
type: 1,
users:[{user:31, type:3},{user: 51, type:1}]
},
{
name: "Nike",
type: 1,
users:[{user:21, type:3},{user: 31, type:1}]
}
总文件数量为200,000 +并且还在增长...... 每个文档都有10,000~5,000个用户..
预期回报
{
isUser: true,
name: "Adidas",
type: 1,
users:[{user:31, type:3},{user: 51, type:1}]
},
{
isUser: false,
name: "Nike",
type: 1,
users:[{user:21, type:3},{user: 31, type:1}]
}
我一直在尝试这个
.aggregate([
{$match:{type:1}},
{$project:
{
isUser:{$elemMatch:["users.user",51]},
users: 1,
type:1,
name: 1
}
}
])
这失败了,我收到错误"超出最大堆栈大小"。我已经尝试了很多组合,似乎没有工作。我真的想避免多次调用mongodb。这可以在一次通话中完成吗?
我被告知要放松,但我有点担心这会导致记忆问题。
如果我使用的是mysql,一个简单的子查询就可以完成这项任务......我希望我能在mongodb中忽略一个类似的简单解决方案。
答案 0 :(得分:0)
处理数组元素的条件并使用 $anyElementTrue
的组合来匹配结果, $ifNull
将数组计算为集合,如果任何元素为真,则返回true否则, $map
运算符将充当安全网,评估以下 $map
表达式并返回表达式的值,如果表达式计算为非空值。 $ifNull
运算符中的 $anyElementTrue
旨在将条件语句表达式应用于users数组中的每个项目,并返回应用了数组的数组结果。然后将使用 评估生成的数组,这将最终计算并返回每个文档的isUser
字段:
db.collection.aggregate([
{ "$match": { "type": 1} },
{
"$project": {
"name": 1, "type": 1,
"isUser": {
"$anyElementTrue": [
{
'$ifNull': [
{
"$map": {
"input": "$users",
"as": "el",
"in": { "$eq": [ "$$el.user",51] }
}
},
[false]
]
}
]
}
}
}
])