在mongodb内部匹配字段 [英] matching fields internally in mongodb
问题描述
我在mongodb中有以下文档
I am having following document in 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:
不是实际数据,但架构完全相同.
Note:
Not an actual data but schema is exactly same.
Requirement:
使用单个查询在学生数组中查找与studentId
和students.id
(id)匹配的文档.
Requirement:
Finding the document which matches the studentId
and students.id
(id inside the students array using single query.
我已经尝试过以下代码
db.data.aggregate({$match:{"students.id":"$studentId"}},{$group:{_id:"$student"}});
Result:
空数组,如果我将{"students.id":"$ studentId"}替换为{"students.id":33},它将返回上面显示的json中的第二个文档.
Result:
Empty Array, If i replace {"students.id":"$studentId"} to {"students.id":33} it is returning the second document in the above shown json.
是否可以使用单个查询获取该场景的文档?
Is it possible to get the documents for this scenario using single query?
推荐答案
如果可能的话,建议您在存储数据时设置条件,以便进行快速的真实性检查(isInStudentsList
).进行这种类型的查询将非常快.
If possible, I'd suggest that you set the condition while storing the data so that you can do a quick truth check (isInStudentsList
). It would be super fast to do that type of query.
否则,有一种相对复杂的方法可以使用Aggregation框架管道在单个查询中执行您想要的操作:
Otherwise, there is a relatively complex way of using the Aggregation framework pipeline to do what you want in a single query:
db.students.aggregate(
{$project:
{studentId: 1, studentIdComp: "$students.id"}},
{$unwind: "$studentIdComp"},
{$project : { studentId : 1,
isStudentEqual: { $eq : [ "$studentId", "$studentIdComp" ] }}},
{$match: {isStudentEqual: true}})
给出您的输入示例,输出将是:
Given your input example the output would be:
{
"result" : [
{
"_id" : ObjectId("517b88decd483543a8bdd95b"),
"studentId" : 23,
"isStudentEqual" : true
}
],
"ok" : 1
}
这些步骤的简要说明:
- 仅使用
studentId
构建文档的投影,并使用仅包含id
的数组构建新字段(因此,第一个文档将包含[23, 55]
. - 使用该结构 $ unwind .这样会为
studentIdComp
数组中的每个数组元素创建一个新的临时文档. - 现在,获取那些文档,并创建一个新的文档投影,该文档投影将继续具有
studentId
,并添加一个名为isStudentEqual
的新字段,该字段将两个字段(studentId
和studentIdComp
)的相等性进行比较.请记住,目前只有一个包含这两个字段的临时文档. - 最后,检查比较值
isStudentEqual
是否为真,并返回那些文档(将包含原始文档_id
和studentId
. - 如果该学生多次出现在列表中,则可能需要将结果分组在
studentId
或_id
上,以防止重复(但我不知道您是否需要这样做).
- Build a projection of the document with just
studentId
and a new field with an array containing just theid
(so the first document it would contain[23, 55]
. - Using that structure, $unwind. That creates a new temporary document for each array element in the
studentIdComp
array. - Now, take those documents, and create a new document projection, which continues to have the
studentId
and adds a new field calledisStudentEqual
that compares the equality of two fields, thestudentId
andstudentIdComp
. Remember that at this point there is a single temporary document that contains those two fields. - Finally, check that the comparison value
isStudentEqual
is true and return those documents (which will contain the original document_id
and thestudentId
. - If the student was in the list multiple times, you might need to group the results on
studentId
or_id
to prevent duplicates (but I don't know that you'd need that).
这篇关于在mongodb内部匹配字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!