在MongoDB中,如何搜索子文档数组? [英] In MongoDB, how do I search in an array of sub-documents?

查看:99
本文介绍了在MongoDB中,如何搜索子文档数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在mongodb中有一个调查文档,每个调查都有surveyRefId用于唯一标识.我无法理解如何在 surveyRefid = 377或360 的文档中找到具有 questionType = hard 的子文档.

I have a survey document in mongodb, each survey have surveyRefId for unique identification. I am not able to understand how to find sub-documents having questionType = hard in documents whose surveyRefid = 377 or 360.

以下是示例文档:

{
  "json": {
    "surveyRefId": 377,
    "surveyName": "survey on sociology",
    "questionsVoList": [
      {
        "questionId": "556708425215763c64b8af3d",
        "questionText": "question no 1",
        "questionTitle": "",
        "questionType": "hard",
        "preQuestion": true,
        "questionOptions": [
          {
            "questionRefId": 0,
            "optionType": "RADIOBUTTON",
            "isanswer": true,
            "optionText": "ch1"
          }
        ]
      },
      {
        "questionId": "556708425215763c64b8af3d",
        "questionText": "question no 2",
        "questionTitle": "",
        "questionType": "simple",
        "question": true,
        "questionOptions": [
          {
            "questionRefId": 0,
            "optionType": "RADIOBUTTON",
            "isanswer": true,
            "optionText": "ch1"
          }
        ],
      },
      {
       "questionId": "556708425215763c64b8af3d",
        "questionText": "question no 3",
        "questionTitle": "",
        "questionType": "hard",
        "questionOptions": [
          {
            "questionRefId": 0,
            "optionType": "RADIOBUTTON",
            "isanswer": true,
            "optionText": "ch1"
          },
          {
            "questionRefId": 0,
            "optionType": "RADIOBUTTON",
            "isanswer": false,
            "optionText": "ch2"
          }
        ],
       }
    ]
  }
}

编辑-根据Sylvain Leroux使用Java驱动程序的解决方案

EDIT-- Solution by using Java driver as per Sylvain Leroux

    BasicDBObject matchSurvey = new BasicDBObject();
    matchSurvey.put("$match", new BasicDBObject("json.surveyRefId", new BasicDBObject("$in", new Integer[]{377,360})));
    BasicDBObject unwind = new BasicDBObject();
    unwind.put("$unwind", "$json.questionsVoList");
    BasicDBObject matchQuestion = new BasicDBObject();
    matchQuestion.put("$match", new BasicDBObject("json.questionsVoList.questionType", "hard"));
    HashMap map = new HashMap();
    map.put("_id", "$_id");
    map.put("questionsVoList", new BasicDBObject("$push", "$json.questionsVoList"));
    BasicDBObject group = new BasicDBObject();
    group.put("$group",map);        
    List<BasicDBObject> list = new ArrayList<BasicDBObject>();
    list.add(matchSurvey);
    list.add(unwind);
    list.add(matchQuestion);
    list.add(group);
    AggregateIterable output = collection.aggregate(list, DBObject.class);

推荐答案

可以找到具有questionType = "hard"的子文档" 可以通过三种不同的方式来理解:

"find sub-documents having questionType = "hard"" can be understood in three different ways:

如果只希望所有文档具有硬查询",则将使用find

If you only want all documents having an "hard query, you will use find and $elemMatch:

db.test.find({"json.surveyRefId": { $in: [377, 360]},
              "json.questionsVoList": {$elemMatch: {"questionType":"hard"}}})

第一个难"查询文档

如果您需要查找文档的第一个"硬"查询,则可以将上述查询与

First "hard" query of a document

If you need to find the first "hard" query of a document, you will combine the above query with the $ projection operator:

db.test.find({"json.surveyRefId": { $in: [377, 360]}, 
              "json.questionsVoList": {$elemMatch: {"questionType":"hard"}}}
             {"json.surveyRefId":1, "json.questionsVoList.$":1})

所有困难查询

如果您需要查找文档的所有所有个硬"查询,则必须使用

All hard queries

If you need to find all "hard" queries of the document, you will have to use the aggregation framework:

db.test.aggregate({$match: { "json.surveyRefId": { $in: [377, 360]} }},
                  {$unwind: "$json.questionsVoList"},
                  {$match: { "json.questionsVoList.questionType": "hard"}},
                  {$group: {_id: "$_id", questionsVoList: {$push: "$json.questionsVoList"}}}
)

  • $match 的第一步将过滤掉不需要的文档根据他们的surveyRefId
  • 然后 $unwind 将为每个子项生成一个文档-文档
  • 另一个 $match 会根据以下内容过滤出不需要的文档questionType
  • 最后, $group 会将所有子文档作为给定<​​c11>
  • 的文档

    • The first $match step will filter out unwanted documents based on their surveyRefId
    • Then $unwind will produce a document for each sub-document
    • An other $match filters out unwanted documents based on questionType
    • Finally, a $group will combine all sub-documents back as one for a given _id
    • 制作:

      {
          "_id" : ObjectId("556828d002509ae174742d11"),
          "questionsVoList" : [
              {
                  "questionId" : "556708425215763c64b8af3d",
                  "questionText" : "question no 1",
                  "questionTitle" : "",
                  "questionType" : "hard",
                  "preQuestion" : true,
                  "questionOptions" : [
                      {
                          "questionRefId" : 0,
                          "optionType" : "RADIOBUTTON",
                          "isanswer" : true,
                          "optionText" : "ch1"
                      }
                  ]
              },
              {
                  "questionId" : "556708425215763c64b8af3d",
                  "questionText" : "question no 3",
                  "questionTitle" : "",
                  "questionType" : "hard",
                  "questionOptions" : [
                      {
                          "questionRefId" : 0,
                          "optionType" : "RADIOBUTTON",
                          "isanswer" : true,
                          "optionText" : "ch1"
                      },
                      {
                          "questionRefId" : 0,
                          "optionType" : "RADIOBUTTON",
                          "isanswer" : false,
                          "optionText" : "ch2"
                      }
                  ]
              }
          ]
      }
      

      这篇关于在MongoDB中,如何搜索子文档数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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