如何在MongoDB中查找同一键值分配给多个值的记录
我有如下数据:如何在MongoDB中查找同一键值分配给多个值的记录,mongodb,mongodb-query,Mongodb,Mongodb Query,我有如下数据: 学生科目 语言 数学 B |科学 A |艺术 C|生物学 B |历史 等等 我想找那些名字相同但只选了两门不同学科的学生,语言和数学 我尝试使用以下查询: $group:{ _id:"$student", sub:"{$addToSet:"$subject"} }, $match:{ sub:{$in:["Language","Math"]} } 但是我没有在MongoDBCompass中预览任何文档。我在虚拟机中工作,Compass只能对生物、历
- 学生科目
- 语言
- 数学
- B |科学
- A |艺术
- C|生物学
- B |历史
$group:{
_id:"$student",
sub:"{$addToSet:"$subject"}
},
$match:{
sub:{$in:["Language","Math"]}
}
但是我没有在MongoDBCompass中预览任何文档。我在虚拟机中工作,Compass只能对生物、历史、科学、艺术进行分组,但不能对语言和数学进行分组。我想得到A
作为我的输出
非常感谢
收集数据和预期输出:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
我希望得到A作为我的输出。您就快到了,只需要对聚合管道进行一些调整:
const pipeline = [
{
$group:
{
_id: '$Student', // Group students by name
subjects: {
$addToSet: '$Subject', // Push all the subjects they take uniquely into an array
},
},
},
{
// Filter for students who only offer Language and Mathematics
$match: { subjects: { $all: ['Language', 'Math'], $size: 2 } },
},
];
db.students.aggregate(pipeline);
这将产生如下输出数组:
[
{ "_id" : studentName1 , "subjects" : [ "Language", "Math" ] },
{ "_id" : studentName2 , "subjects" : [ "Language", "Math" ] },
....
]
您就快到了,只需要对聚合管道进行一些调整:
const pipeline = [
{
$group:
{
_id: '$Student', // Group students by name
subjects: {
$addToSet: '$Subject', // Push all the subjects they take uniquely into an array
},
},
},
{
// Filter for students who only offer Language and Mathematics
$match: { subjects: { $all: ['Language', 'Math'], $size: 2 } },
},
];
db.students.aggregate(pipeline);
这将产生如下输出数组:
[
{ "_id" : studentName1 , "subjects" : [ "Language", "Math" ] },
{ "_id" : studentName2 , "subjects" : [ "Language", "Math" ] },
....
]
您必须使用聚合运算符。运算符仅用于检查数组中的一个值。我想你正在考虑
查询:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
结果:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
注意:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
如果将[“语言”、“数学”]
替换为[“历史”]
,您将得到结果:{“匹配的学生”:“B”}
您还可以尝试查看其他,如$allegementstrue
。使用最适合您的应用程序的
[编辑添加]
学生受试者的样本数据
收集:
{ "_id" : 1, "student" : "A", "subject" : "Language" }
{ "_id" : 2, "student" : "A", "subject" : "Math" }
{ "_id" : 3, "student" : "B", "subject" : "Science" }
{ "_id" : 4, "student" : "A", "subject" : "Arts" }
{ "_id" : 5, "student" : "C", "subject" : "Biology" }
{ "_id" : 6, "student" : "B", "subject" : "History" }
每个阶段后的结果:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
第一阶段:$group
{ "_id" : "C", "studentSubjects" : [ "Biology" ] }
{ "_id" : "B", "studentSubjects" : [ "History", "Science" ] }
{ "_id" : "A", "studentSubjects" : [ "Arts", "Math", "Language" ] }
第二阶段:$project
{ "_id" : "C", "subjectMatches" : false }
{ "_id" : "B", "subjectMatches" : false }
{ "_id" : "A", "subjectMatches" : true }
{ "matched_student" : "A" }
第三阶段:$match
{ "_id" : "A", "subjectMatches" : true }
第四阶段:$project
{ "_id" : "C", "subjectMatches" : false }
{ "_id" : "B", "subjectMatches" : false }
{ "_id" : "A", "subjectMatches" : true }
{ "matched_student" : "A" }
您必须使用聚合运算符。运算符仅用于检查数组中的一个值。我想你正在考虑
查询:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
结果:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
注意:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
如果将[“语言”、“数学”]
替换为[“历史”]
,您将得到结果:{“匹配的学生”:“B”}
您还可以尝试查看其他,如$allegementstrue
。使用最适合您的应用程序的
[编辑添加]
学生受试者的样本数据
收集:
{ "_id" : 1, "student" : "A", "subject" : "Language" }
{ "_id" : 2, "student" : "A", "subject" : "Math" }
{ "_id" : 3, "student" : "B", "subject" : "Science" }
{ "_id" : 4, "student" : "A", "subject" : "Arts" }
{ "_id" : 5, "student" : "C", "subject" : "Biology" }
{ "_id" : 6, "student" : "B", "subject" : "History" }
每个阶段后的结果:
{ Student:"A", Subject:"Language" },
{ Student:"A", Subject:"Math" },
{ Student:"B", Subject:"Science" },
{ Student:"A", Subject:"Arts" },
{ Student:"C", Subject:"Biology" },
{ Student:"B", Subject:"History" }
db.student_subjects.aggregate( [
{ $group: {
_id: "$student",
studentSubjects: { $addToSet: "$subject" }
}
},
{ $project: {
subjectMatches: { $setIsSubset: [ [ "Language", "Math" ], "$studentSubjects" ] }
}
},
{ $match: {
subjectMatches: true
}
},
{ $project: {
matched_student: "$_id", _id: 0
}
}
] )
{ "matched_student" : "A" }
第一阶段:$group
{ "_id" : "C", "studentSubjects" : [ "Biology" ] }
{ "_id" : "B", "studentSubjects" : [ "History", "Science" ] }
{ "_id" : "A", "studentSubjects" : [ "Arts", "Math", "Language" ] }
第二阶段:$project
{ "_id" : "C", "subjectMatches" : false }
{ "_id" : "B", "subjectMatches" : false }
{ "_id" : "A", "subjectMatches" : true }
{ "matched_student" : "A" }
第三阶段:$match
{ "_id" : "A", "subjectMatches" : true }
第四阶段:$project
{ "_id" : "C", "subjectMatches" : false }
{ "_id" : "B", "subjectMatches" : false }
{ "_id" : "A", "subjectMatches" : true }
{ "matched_student" : "A" }
请,你能分享一下学生文件的样子吗?{学生:“A”,科目:“语言”},{学生:“A”,科目:“数学”},{学生:“B”,科目:“科学”},{学生:“A”,科目:“艺术”},{学生:“C”,科目:“生物”},{学生:“B”,科目:“历史”}我想得到A作为我的输出是这些文件的
\u id
学生姓名?如果是这样,那就行不通了\u id
在集合中必须是唯一的。如果有多个学生只学习“数学”和“语言”,你应该让所有学生都正确吗?@OTZ我需要让同名的学生学习数学和语言。例如,A学习了两门学科数学和语言,所以需要在输出中输入A的名字,请,你能分享一下学生文件的样子吗?{学生:“A”,科目:“语言”},{学生:“A”,科目:“数学”},{学生:“B”,科目:“科学”},{学生:“A”,科目:“艺术”},{学生:“C”,科目:“生物”},{学生:“B”,科目:“历史”}我想得到A作为我的输出是这些文件的\u id
学生姓名?如果是这样,那就行不通了\u id
在集合中必须是唯一的。如果有多个学生同时学习“数学”和“语言”,你应该让所有学生都正确吗?@OTZ我需要让同名的学生学习数学和语言i.e。,A学习了两门学科数学和语言,因此需要在输出中获得A的名称Hanks prasad logics似乎不错,但我正在MongoDB compass中运行上述管道,聚合无法识别学科数学和语言,但它能够找到其他学科。这是一种我可以直接发送数学和语言值的方式,而不是依赖于studentSubjects:{$addToSet:“$subject”}。感谢您的帮助。我成功地尝试了上面的代码-无论是在mongoshell
还是Compass(1.19版)中。另外,我正在使用MongoDB 4.0版。可能是,您正在为集合使用不同的字段名(或不同的大写/小写)。请再检查一次。我检查了所有内容,但我无法将数学和语言归为A。我想知道为什么。我不能只对数学和语言进行分组。其他科目正在分组。我刚才在答案中添加了聚合管道每个阶段后的结果。您可以看到如何转换数据以获得最终的预期结果。这就是正在运行的聚合管道!解释非常清楚,我不知道我遗漏了什么,但我无法得到预期的结果。无论如何,感谢您的帮助。感谢prasad logics似乎不错,但我正在MongoDB compass中运行上述管道,聚合无法识别主题数学和语言,但它能够找到其他主题。这是一种我可以直接发送数学和语言值的方式,而不是依赖于studentSubjects:{$addToSet:“$subject”}。谢谢你的帮助,我可以试试