在mongodb内部匹配字段 [英] matching fields internally in mongodb

查看:164
本文介绍了在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:使用单个查询在学生数组中查找与studentIdstudents.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
}

这些步骤的简要说明:

  1. 仅使用studentId构建文档的投影,并使用仅包含id的数组构建新字段(因此,第一个文档将包含[23, 55].
  2. 使用该结构 $ unwind .这样会为studentIdComp数组中的每个数组元素创建一个新的临时文档.
  3. 现在,获取那些文档,并创建一个新的文档投影,该文档投影将继续具有studentId,并添加一个名为isStudentEqual的新字段,该字段将两个字段(studentIdstudentIdComp)的相等性进行比较.请记住,目前只有一个包含这两个字段的临时文档.
  4. 最后,检查比较值isStudentEqual是否为真,并返回那些文档(将包含原始文档_idstudentId.
  5. 如果该学生多次出现在列表中,则可能需要将结果分组在studentId_id上,以防止重复(但我不知道您是否需要这样做).
  1. Build a projection of the document with just studentId and a new field with an array containing just the id (so the first document it would contain [23, 55].
  2. Using that structure, $unwind. That creates a new temporary document for each array element in the studentIdComp array.
  3. Now, take those documents, and create a new document projection, which continues to have the studentId and adds a new field called isStudentEqual that compares the equality of two fields, the studentId and studentIdComp. Remember that at this point there is a single temporary document that contains those two fields.
  4. Finally, check that the comparison value isStudentEqual is true and return those documents (which will contain the original document _id and the studentId.
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆