这是我的文件:
members: [
{
_id: 'id1'
name: 'Jack',
group: 0
},
{
_id: 'id2'
name: 'Rose',
group: 0
},
{
_id: 'id3'
name: 'Tom',
group: 1
}
]
我想通过memberId搜索某个人的所有成员以及所有成员的总数。
例如,当我输入id1
时,它将返回:
{
count: 3,
members: [
{
_id: 'id1',
name: 'Jack'
},
{
_id: 'id2',
name: 'Rose'
}
]
}
当我输入id3
时,它将返回:
{
count: 3,
members: [
{
_id: 'id3',
name: 'Tom'
}
]
}
我试图这样做:
db.collectionName.aggregate({
$project: {
count: {$size: '$members'},
members: 1
}
},
{
$unwind: '$members'
},
{
$project: {
count: 1,
members: {
$cond: [{$eq: ['$members._id', TheInputMemberId]}, '$member', null]
}
}
})
但是,过滤器只包含_id
而不是_id
和group
,因此结果始终只有一个成员。
我不知道如何首先获取组变量,然后进行过滤。
期待您的回复!谢谢!
答案 0 :(得分:1)
你可以尝试这样的事情。添加了项目和组阶段,以便在传递了id的任何结果元素匹配时保留数据结果。
$map 在每个数据结果元素中应用传递的id和id之间的等于比较,并生成具有true和false值的数组。 $anyElementTrue 检查此数组,仅当数组中至少有一个true值时才返回true。匹配阶段仅包含匹配值为true的元素。
aggregate({
"$project": {
"count": {
"$size": "$members"
},
"members": 1
}
}, {
"$unwind": "$members"
}, {
"$group": {
"_id": "$members.group",
"data": {
"$push": {
"name": "$members.name",
"_id": "$members._id"
}
},
"count": {
"$first": "$count"
}
}
}, {
"$project": {
"_id": 1,
"data": 1,
"matched": {
"$anyElementTrue": {
"$map": {
"input": "$data",
"as": "result",
"in": {
"$eq": ['$$result._id', 'id1']
}
}
}
}
}
}, {
"$match": {
"matched": true
}
}).pretty()
替代版本:
与上述版本类似,但这个版本将项目和匹配阶段合二为一。 $cond 与 $redact 帐户匹配,当找到匹配时,它会保持匹配完整的树或丢弃它。
aggregate({
"$project": {
"count": {
"$size": "$members"
},
"members": 1
}
}, {
"$unwind": "$members"
}, {
"$group": {
"_id": "$members.group",
"data": {
"$push": {
"name": "$members.name",
"_id": "$members._id"
}
},
"count": {
"$first": "$count"
}
}
}, {
"$redact": {
"$cond": [{
"$anyElementTrue": {
"$map": {
"input": "$data",
"as": "result",
"in": {
"$eq": ['$$result._id', 'id1']
}
}
}
},
"$$KEEP",
"$$PRUNE"
]
}
}).pretty()