我在mongodb中有以下文件
{
"_id" : ObjectId("517b88decd483543a8bdd95b"),
"studentId" : 23,
"students" : [
{
"id" : 23,
"class" : "a"
},
{
"id" : 55,
"class" : "b"
}
]
}
{
"_id" : ObjectId("517b9d05254e385a07fc4e71"),
"studentId" : 55,
"students" : [
{
"id" : 33,
"class" : "c"
}
]
}
Note:
不是实际数据,但架构完全相同。
Requirement:
使用单个查询查找与studentId
和students.id
匹配的文档(学生数组中的ID。
我已尝试过以下代码
db.data.aggregate({$match:{"students.id":"$studentId"}},{$group:{_id:"$student"}});
Result:
空数组,如果我将{“students.id”:“$ studentId”}替换为{“students.id”:33}它将返回上面显示的json中的第二个文档。
是否可以使用单个查询获取此方案的文档?
答案 0 :(得分:13)
如果可能的话,我建议您在存储数据时设置条件,以便快速进行真相检查(isInStudentsList
)。这种类型的查询会非常快。
否则,有一种相对复杂的方法可以使用聚合框架管道在单个查询中执行您想要的操作:
db.students.aggregate(
{$project:
{studentId: 1, studentIdComp: "$students.id"}},
{$unwind: "$studentIdComp"},
{$project : { studentId : 1,
isStudentEqual: { $eq : [ "$studentId", "$studentIdComp" ] }}},
{$match: {isStudentEqual: true}})
根据您的输入示例,输出将为:
{
"result" : [
{
"_id" : ObjectId("517b88decd483543a8bdd95b"),
"studentId" : 23,
"isStudentEqual" : true
}
],
"ok" : 1
}
步骤的简要说明:
studentId
和仅包含id
的数组的新字段构建文档投影(因此第一个文档将包含[23, 55]
。studentIdComp
数组中的每个数组元素创建了一个新的临时文档。studentId
并添加一个名为isStudentEqual
的新字段,用于比较两个字段的相等性,{{1} }和studentId
。请记住,此时有一个包含这两个字段的临时文档。studentIdComp
是否为真并返回这些文档(包含原始文档isStudentEqual
和_id
。studentId
或studentId
以防止重复(但我不知道您需要这样做)。 答案 1 :(得分:0)
不幸的是,这是不可能的;(
要解决此问题,必须使用 $ where 语句 (例如:Finding embeded document in mongodb?),
但 $ where 限制与汇总框架一起使用
答案 2 :(得分:-1)
db.data.find({students: {$elemMatch: {id: 23}} , studentId: 23});