如何在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”}。谢谢你的帮助,我可以试试