MongoDb聚合:当给定array-1和array-2时,如何根据另一个array-2对array-1进行分组


编辑:我最初的问题是

MongoDb聚合:你能在$lookup阶段的pipline中对输入文档变量进行$unroll吗?

考虑下面的代码:

{$lookup: {
from:"mydoc", 
let: {"c":"$myArray"}, 
pipeline: [ 
{$unwind: "$$c"},
]
as:"myNewDoc"
}}

如果我想的话,我该如何解除c

/////原始问题结束

-----编辑-----

从Tom Slabbaert的评论中,我们现在知道可以在$lookup阶段的pipline中对输入文档变量进行$unroll。但不建议这样做。

我想要实现什么?

考虑一下这些集合,pollcastedvote来自我问的一个问题的答案。

我正在尝试获得如下输出:

numberOfVotes: 6,
hasThisUserVoted: true,
numberOfComments: 12,
castedVotesPerChoice:{
"choiceA": [
{"_id": ObjectId("..."), "voter": "Juzi", "choice": 0, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Juma", "choice": 0, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Jane", "choice": 0, "pollId": 100 },
],
"choiceB": [
{"_id": ObjectId("..."), "voter": "Jamo", "choice": 1, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Juju", "choice": 1, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Jana", "choice": 1, "pollId": 100 }
],
"choiceC": [ ]
}

我目前的实现:

db.poll.aggregate([
{"$match": {"_id": 100}}, 
// ...lookup to get comments
{"$lookup": {
"from":"castedvotes", 
"let": {"pollId":"$_id"}, 
"pipeline":[
{"$match":
{"$expr":
{"$eq": ["$pollId", "$$pollId"]},
}},
], 
"as":"votes" // will use this to get number of votes and find out if the authenticated user has voted.
}},
{"$unwind":"$choices"},
{"$lookup": {
"from":"castedvotes", 
"let": {"c":"$choices"}, 
"pipeline":[
{"$match":
{"$expr":
{"$eq": ["$choice", "$$c.id"]},
}},
], 
"as":"votesPerChoice"
}},
])

我目前的实现存在的问题是,它对同一个集合进行了两次查找。我觉得这是不必要的,而且它会使代码不干燥。有了$unwind,我知道我可以取消这里描述的$unwind

所以我的问题是,我如何通过一次$lookup到casted voice集合来获得我想要的输出?由于两个查找都返回相同的数据。

或者问一个不同的问题,当给定array-1和array-2时,我如何在mongodb聚合中基于另一个array-2对array-1进行分组?

这个问题回答了如何通过某种方式构造$lookup阶段,在mongodb聚合中基于另一个数组对数组进行分组。它不能回答我的问题。

如果我已经理解了;谜题;张贴正确(张贴标题和EDIT是不同的用例(,我们可以使用单个$lookup:获得所需的结果

db.poll.aggregate([
{
"$match": {
"_id": 100
}
},
{
"$lookup": {
"from": "castedvotes",
"localField": "pollId",
"foreignField": "choices.id",
"as": "voters"
}
},
{
$project: {
numberOfVotes: {
$size: "$voters"
},
hasThisUserVoted: {
$in: [
"$_id",
"$voters.pollId"
]
},
/**How to calculate it?*/
numberOfComments: {
$multiply: [
{
$size: "$voters"
},
2
]
},
castedVotesPerChoice: {
$arrayToObject: {
$map: {
input: "$choices",
as: "choice",
in: {
k: "$$choice.name",
v: {
$filter: {
input: "$voters",
as: "voter",
cond: {
$eq: [
"$$voter.choice",
"$$choice.id"
]
}
}
}
}
}
}
}
}
}
])

MongoPlayground

最新更新