[英]MongoDB aggregate different collections
i've been trying to do this aggregation since yesterday with no luck, hope you guys can give me some ideas.从昨天开始,我一直在尝试进行这种聚合,但没有成功,希望你们能给我一些想法。 A little background, I have 2 collections, one for results and another for questions.一点背景,我有 2 个 collections,一个用于结果,另一个用于问题。 Results is basically where people solve questions, so it can have 1 question or up to 99 if i'm not mistaken.结果基本上是人们解决问题的地方,所以如果我没记错的话,它可以有 1 个问题或最多 99 个问题。 This is the simplified schema:这是简化的架构:
Results Schema:
_id: ObjectId("6010664ac5c4f77f26f5d005")
questions: [
{
_id: ObjectId("5d2627c94bb703bfcc910763"),
correct: false
},
{
_id: ObjectId("5d2627c94bb703bfcc910764"),
correct: true
},
{
_id: ObjectId("5d2627c94bb703bfcc910765"),
correct: true
}
]
So, on this specific object, the user answered 3 questions and got 2 of them correct.因此,对于这个特定的 object,用户回答了 3 个问题并答对了其中 2 个。
Questions Schema:
_id: ObjectId("5d2627c94bb703bfcc910763")
What i'm struggling to do is: for each element in all the questions schema, I have to check if the question was answered - ie (check if there's an _id of questions array == _id on the Questions Schema, yes there can be multiple questions with the same _id as Questions Schema, but Questions Schema _id is unique).我正在努力做的是:对于所有问题模式中的每个元素,我必须检查问题是否已得到回答 - 即(检查问题模式中是否有问题数组 == _id 的 _id,是的,可以_id 与 Questions Schema 相同的多个问题,但 Questions Schema _id 是唯一的)。 If that question was answered, I need to check if correct = true, if so, I add it to a correctAnswer variable, if not, wrongAnswer.如果回答了该问题,我需要检查是否正确 = 真,如果是,我将其添加到 correctAnswer 变量,如果不是,则添加 wrongAnswer。
I've tried many things so far with conditions, group to get the $sum of correct and wrong answers, lookup to join both collections but so far, I can't even get to show just the aggregation result.到目前为止,我已经尝试了很多有条件的事情,分组以获得正确和错误答案的 $sum,查找以加入 collections 但到目前为止,我什至无法只显示聚合结果。
One of the things I tried (i was trying to do baby steps first) but as mentioned before, couldn't even get the result printed.我尝试过的其中一件事(我试图先做婴儿步骤)但如前所述,甚至无法打印结果。
Result.aggregate([
$lookup: {
from: 'question',
localField: 'questions._id',
foreignField: '_id',
as: 'same'
},
But this gets me both collections combined, and 'same' comes as empty array, tried using match with also no luck.但这让我得到了 collections 组合,并且“相同”作为空数组出现,尝试使用匹配也没有运气。 I also did a $project to just get the information I wanted我还做了一个 $project 来获取我想要的信息
$project: {
_id: 0,
questions: {
_id: 1,
correct: 1
}
},
Tried using $group: $group: { _id: "$_id", $cond: {if: {"$correct": { $eq: true}}, then: {testField: {$sum: 1}}, else: {testField: 0}} } And as I said, i was just trying to do baby steps so it the testField was beeing manually set, also tried many other things from stackoverflow.尝试使用 $group: $group: { _id: "$_id", $cond: {if: {"$correct": { $eq: true}}, then: {testField: {$sum: 1}}, else : {testField: 0}} } 正如我所说,我只是想做一些小步骤,所以 testField 是手动设置的,还尝试了 stackoverflow 中的许多其他东西。 Would appreciate the help and sorry for the very long text, just wanted to put in some examples that I did and tried.感谢您的帮助,对于很长的文字感到抱歉,只是想举一些我做过和尝试过的例子。
TLDR : Need to find a question
from the Results Schema
where _id
matches an _id
from the Questions Schema
, if there is, check if correct: true
or correct: false
. TLDR :需要从Results Schema
中找到一个question
,其中_id
与Questions Schema
中的_id
匹配,如果有,请检查correct: true
或correct: false
。 Update Questions Schema
accordingly with how many were correct and how many were wrong for each question
from Questions Schema
.根据 Questions Schema 中的每个question
,相应地更新Questions Schema
Questions Schema
多少是正确的,有多少是错误的。 Example: newField: {correctAnswer: 4, wrongAnswer: 3}
so in this case, there were 7 questions from the Result schema
question
array that matched an _id
from Question Schema
, 4 had correct: true
and 3 had correct: false
.示例: newField: {correctAnswer: 4, wrongAnswer: 3}
所以在这种情况下, Result schema
question
数组中有 7 个问题与Question Schema
中的_id
匹配,4 个correct: true
,3 个correct: false
。 Then it goes on like this for the rest of Question Schema
然后对于Question Schema
的 rest 这样继续下去
I don't know of a way to "$lookup"
and update
at the same time.我不知道同时"$lookup"
和update
的方法。 There's probably a better way to do this, but the aggregation pipeline below creates the documents that could be used in a subsequent update
.可能有更好的方法来执行此操作,但下面的聚合管道会创建可在后续update
中使用的文档。 The pipeline correctly counts repeat questions by a single Result
_id
, in case someone keeps trying a question until they get it right.管道通过单个Result
_id
正确地计算重复问题,以防有人不断尝试一个问题直到他们做对为止。 One possible issue is that if a question has no Result
answers, then no "newField": { "correctAnswers": 0, "wrongAnswers": 0 }
document is created.一个可能的问题是,如果问题没有Result
答案,则不会创建"newField": { "correctAnswers": 0, "wrongAnswers": 0 }
文档。
db.Question.aggregate([
{
// lookup documents in Result that match _id
"$lookup": {
"from": "Result",
"localField": "_id",
"foreignField": "questions._id",
"as": "results"
}
},
{
// unwind everything
"$unwind": "$results"
},
{
// more of everything
"$unwind": "$results.questions"
},
{
// only keep answers that match question
"$match": {
"$expr": { "$eq": [ "$_id", "$results.questions._id" ] }
}
},
{
// reassemble and count correct/wrong answers
"$group": {
"_id": "$_id",
"correct": {
"$sum": {
"$cond": [ { "$eq": [ "$results.questions.correct", true ] }, 1, 0 ]
}
},
"wrong": {
"$sum": {
"$cond": [ { "$eq": [ "$results.questions.correct", false ] }, 1, 0 ]
}
}
}
},
{
// project what you want as output
"$project": {
newField: {
correctAnswers: "$correct",
wrongAnswers: "$wrong"
}
}
}
])
Try it on mongoplayground.net .在mongoplayground.net上试用。
For a scenario where "$lookup"
can't be used because the Question
collection is in a different database, the Result
collection may be used to generate output documents to update the Question
collection.对于因为Question
集合在不同的数据库中而无法使用"$lookup"
的场景,可以使用Result
集合生成output个文档来更新Question
集合。
Here's one way to do it.这是一种方法。
db.Result.aggregate([
{
"$unwind": "$questions"
},
{
"$group": {
"_id": "$questions._id",
"correct": {
"$push": "$questions.correct"
}
}
},
{
"$project": {
"newField": {
"correctAnswers": {
"$size": {
"$filter": {
"input": "$correct",
"as": "bool",
"cond": "$$bool"
}
}
},
"wrongAnswers": {
"$size": {
"$filter": {
"input": "$correct",
"as": "bool",
"cond": { "$not": "$$bool" }
}
}
}
}
}
}
])
Try it on mongoplayground.net .在mongoplayground.net上试用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.