我目前正在尝试弄清楚如何为数组中的某些对象创建组。例如,根据下面的文档结构,我想创建一个$group
,其中只有id
为5和4的人才会被处理到该组中。
我在伪代码中试图实现的目标:
{ $unwind:"$people" },
{ $group: {
if("$people.id"===5 || "$people.id"===4){
_id: $people.id
averageScore: {$avg: "$score"}
}
}}
这将返回两个文档,一个文档的_id
为5,averageScore
为10,一个文档为_id
4,averageScore
为13.5
示例文档结构:
doc 1
{
gameId:394028,
people: [{
id: 5,
score: 10,
mapSide: 'left'
},{
id: 4,
score: 14,
mapSide: 'right'
},{
id: 1,
score: 11,
mapSide: 'right'
},{
id: 2,
score: 12,
mapSide: 'left'
}]
}
doc 2
{
gameId:394028,
people: [{
id: 7,
score: 5,
mapSide: 'left'
},{
id: 9,
score: 10,
mapSide: 'right'
},{
id: 4,
score: 13,
mapSide: 'right'
},{
id: 1,
score: 12
mapSide: 'left'
}]
}
答案 0 :(得分:2)
你应该能够使用像
这样的东西{ $unwind:"$people" },
{ $match:{$or :[{'people.id' : 4}, {'people.id' :5}]} },
{ $group: {_id:"$people.id"
averageScore: {$avg: "$score"}}
$match
基本上会过滤你的展开集合,就像find命令一样(采用相同的语法)并将匹配的文档传递给下一个阶段。如果您要匹配很多ID,则可以将$or
替换为'people.id':{$in:[4,5]}
。
修改:评论后此管道的详细说明:
问题的前两个管道阶段到doc1会发生什么:
{ $unwind:"$people" }
结果:
{gameId:394028, people: {id: 5, score: 10, mapSide: 'left'}},
{gameId:394028, people: {id: 4, score: 14, mapSide: 'right'}},
{gameId:394028, people: {id: 1, score: 11, mapSide: 'right'}},
{gameId:394028, people: {id: 2, score: 12, mapSide: 'left' }},
{ $match:{$or :[{'people.id' : 4}, {'people.id' :5}]} }
结果:
{gameId:394028, people: {id: 5, score: 10, mapSide: 'left'}},
{gameId:394028, people: {id: 4, score: 14, mapSide: 'right'}},
之后,您仍然可以访问$group
阶段原始文档中可用的所有字段。