如何在mongodb中检索部分嵌入文件与数组相比?

时间:2015-12-02 06:38:25

标签: node.js mongodb mongodb-query aggregation-framework

我想得到与arr值相对应的具体问题。我试过$ where,$ in $ projection但是没有工作。其中in运算符只给出一个问题,即问题No 1意味着它找到问题1 arr和when当它发现它只返回但我想要对应于数组中其他值的问题。请帮忙。

 var arr=["3","1","5","2","4"];
db.exammasters.find({'examid':"1026","questionMaster.questionNo":{$in:["3","1","5","2","4"]}},{_id: 0, questionMaster: {$elemMatch:{questionNo:{$in:["3","1","5","2","4"]}}},'questionMaster.answer':0})

这是我的文件

{

    "_id": "5649e095b945ebd412000046",
    "examid": "1026",
    "name": "C++",
    "description": "C++ exam",
    "questionLimit": 5,
    "examDuration": 5,
    "__v": 0,
    "questionMaster": [
      {
        "questionNo": "1",
        "questionText": "Is bool a fundamental datatype in C++?",
        "answer": "5149532885f5543cb3dc7865c1b41b6a",
        "_id": "5649e095b945ebd41200007a",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "Yes",
            "_id": "5649e095b945ebd41200007e"
          },
          {
            "optionNo": "2",
            "optionText": "No, it is a typedef of unsigned char",
            "_id": "5649e095b945ebd41200007d"
          },
          {
            "optionNo": "3",
            "optionText": "No, it is an enum of {false,true}",
            "_id": "5649e095b945ebd41200007c"
          },
          {
            "optionNo": "4",
            "optionText": "No, it is expanded from macros",
            "_id": "5649e095b945ebd41200007b"
          }
        ]
      },
      {
        "questionNo": "2",
        "questionText": "Find the odd one out:",
        "answer": "6e4fc780d5604c5160f859df934436fb",
        "_id": "5649e095b945ebd412000075",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "std::vector<int>",
            "_id": "5649e095b945ebd412000079"
          },
          {
            "optionNo": "2",
            "optionText": " std::vector<short>",
            "_id": "5649e095b945ebd412000078"
          },
          {
            "optionNo": "3",
            "optionText": " std::vector<long>",
            "_id": "5649e095b945ebd412000077"
          },
          {
            "optionNo": "4",
            "optionText": "std::vector<bool>",
            "_id": "5649e095b945ebd412000076"
          }
        ]
      },
      {
        "questionNo": "3",
        "questionText": " What happens when a null pointer is converted into bool?",
        "answer": "4277f0f85e152d162d9433a63f8cf5de",
        "_id": "5649e095b945ebd412000070",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "An error is flagged",
            "_id": "5649e095b945ebd412000074"
          },
          {
            "optionNo": "2",
            "optionText": "bool value evaluates to true",
            "_id": "5649e095b945ebd412000073"
          },
          {
            "optionNo": "3",
            "optionText": "bool value evaluates to false",
            "_id": "5649e095b945ebd412000072"
          },
          {
            "optionNo": "4",
            "optionText": " the statement is ignored",
            "_id": "5649e095b945ebd412000071"
          }
        ]
      },
      {
        "questionNo": "4",
        "questionText": "Which of the following statements are false?",
        "answer": "eaf0eec3ced4c8f4945ac3e1312ba84f",
        "_id": "5649e095b945ebd41200006b",
        "Options": [
          {
            "optionNo": "1",
            "optionText": " bool can have two values and can be used to express logical expressions",
            "_id": "5649e095b945ebd41200006f"
          },
          {
            "optionNo": "2",
            "optionText": "bool cannot be used as the type of the result of the function.",
            "_id": "5649e095b945ebd41200006e"
          },
          {
            "optionNo": "3",
            "optionText": " bool can be converted into integers implicitly",
            "_id": "5649e095b945ebd41200006d"
          },
          {
            "optionNo": "4",
            "optionText": " a bool value can be used in arithemetic expressions.",
            "_id": "5649e095b945ebd41200006c"
          }
        ]
      },
      {
        "questionNo": "5",
        "questionText": " For what values of the expression is an if-statement block not executed?",
        "answer": "eaf0eec3ced4c8f4945ac3e1312ba84f",
        "_id": "5649e095b945ebd412000068",
        "Options": [
          {
            "optionNo": "1",
            "optionText": " 0 and all negative values",
            "_id": "5649e095b945ebd41200006a"
          },
          {
            "optionNo": "2",
            "optionText": "0",
            "_id": "5649e095b945ebd412000069"
          }
        ]
      },
      {
        "questionNo": "6",
        "questionText": "A pointer is",
        "answer": "6e4fc780d5604c5160f859df934436fb",
        "_id": "5649e095b945ebd412000063",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "A keyword used to create variables",
            "_id": "5649e095b945ebd412000067"
          },
          {
            "optionNo": "2",
            "optionText": "A variable that stores address of an instruction",
            "_id": "5649e095b945ebd412000066"
          },
          {
            "optionNo": "3",
            "optionText": "A variable that stores address of other variable",
            "_id": "5649e095b945ebd412000065"
          },
          {
            "optionNo": "4",
            "optionText": "All of the above",
            "_id": "5649e095b945ebd412000064"
          }
        ]
      },
      {
        "questionNo": "7",
        "questionText": "Which of the two operators ++ and — work for the bool datatype in C++?",
        "answer": "eaf0eec3ced4c8f4945ac3e1312ba84f",
        "_id": "5649e095b945ebd41200005e",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "None",
            "_id": "5649e095b945ebd412000062"
          },
          {
            "optionNo": "2",
            "optionText": "++",
            "_id": "5649e095b945ebd412000061"
          },
          {
            "optionNo": "3",
            "optionText": "--",
            "_id": "5649e095b945ebd412000060"
          },
          {
            "optionNo": "4",
            "optionText": "both",
            "_id": "5649e095b945ebd41200005f"
          }
        ]
      },
      {
        "questionNo": "8",
        "questionText": " The size_t integer type in C++ is?",
        "answer": "4277f0f85e152d162d9433a63f8cf5de",
        "_id": "5649e095b945ebd41200005a",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "Unsigned integer of at least 64 bits",
            "_id": "5649e095b945ebd41200005d"
          },
          {
            "optionNo": "2",
            "optionText": "Signed integer of at least 16 bits",
            "_id": "5649e095b945ebd41200005c"
          },
          {
            "optionNo": "3",
            "optionText": "Unsigned integer of at least 16 bits",
            "_id": "5649e095b945ebd41200005b"
          }
        ]
      },
      {
        "questionNo": "9",
        "questionText": " Which of these expressions will return true if the input integer v is a power of two?",
        "answer": "4277f0f85e152d162d9433a63f8cf5de",
        "_id": "5649e095b945ebd412000056",
        "Options": [
          {
            "optionNo": "1",
            "optionText": " (v | (v + 1)) == 0;",
            "_id": "5649e095b945ebd412000059"
          },
          {
            "optionNo": "2",
            "optionText": "(v | (v – 1)) == 0;",
            "_id": "5649e095b945ebd412000058"
          },
          {
            "optionNo": "3",
            "optionText": "(v & (v – 1)) == 0;",
            "_id": "5649e095b945ebd412000057"
          }
        ]
      },
      {
        "questionNo": "10",
        "questionText": "How does a sequence of objects are accessed in c++?",
        "answer": "4277f0f85e152d162d9433a63f8cf5de",
        "_id": "5649e095b945ebd412000051",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "Iterators",
            "_id": "5649e095b945ebd412000055"
          },
          {
            "optionNo": "2",
            "optionText": "Pointers",
            "_id": "5649e095b945ebd412000054"
          },
          {
            "optionNo": "3",
            "optionText": "Both a & b",
            "_id": "5649e095b945ebd412000053"
          },
          {
            "optionNo": "4",
            "optionText": " None of the mentioned",
            "_id": "5649e095b945ebd412000052"
          }
        ]
      },
      {
        "questionNo": "11",
        "questionText": "How many parameters are present in mismatch method in non-sequence modifying algorithm?",
        "answer": "6e4fc780d5604c5160f859df934436fb",
        "_id": "5649e095b945ebd41200004c",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "1",
            "_id": "5649e095b945ebd412000050"
          },
          {
            "optionNo": "2",
            "optionText": "2",
            "_id": "5649e095b945ebd41200004f"
          },
          {
            "optionNo": "3",
            "optionText": "3",
            "_id": "5649e095b945ebd41200004e"
          },
          {
            "optionNo": "4",
            "optionText": "4",
            "_id": "5649e095b945ebd41200004d"
          }
        ]
      },
      {
        "questionNo": "12",
        "questionText": "What will happen in ‘all_of’ method if the range is empty?",
        "answer": "5149532885f5543cb3dc7865c1b41b6a",
        "_id": "5649e095b945ebd412000047",
        "Options": [
          {
            "optionNo": "1",
            "optionText": "Return true",
            "_id": "5649e095b945ebd41200004b"
          },
          {
            "optionNo": "2",
            "optionText": "Return false",
            "_id": "5649e095b945ebd41200004a"
          },
          {
            "optionNo": "3",
            "optionText": "Return nothing",
            "_id": "5649e095b945ebd412000049"
          },
          {
            "optionNo": "4",
            "optionText": "None of the mentioned",
            "_id": "5649e095b945ebd412000048"
          }
        ]
      }
    ],
    "instructionsDetails": [
      {
        "_id": "5649e095b945ebd41200007f",
        "Instructions": [
          {
            "instructionNo": "1",
            "instruction": "This is C++ Exam Quiz Conducted by Esko",
            "_id": "5649e095b945ebd412000081"
          },
          {
            "instructionNo": "2",
            "instruction": "Follow Rules and regulations",
            "_id": "5649e095b945ebd412000080"
          }
        ]
      }
    ]
  }
]

2 个答案:

答案 0 :(得分:0)

您可以使用聚合框架来实现此目的。查找查询不会帮助您。示例聚合查询如下所示:

db.exammasters.aggregate(
  {$match: {examid:"1026"}},
  {$unwind: "$questionMaster"},
  {$match: {"questionMaster.questionNo": {$in : arr}}},
)

答案 1 :(得分:0)

从版本3.2开始,您可以使用$filter运算符返回一个只包含符合条件的元素的数组。

var myArray = [ "3", "1", "5", "2", "4" ];

db.collection.aggregate([
    { "$match": {
       "examid": "1026",
       "questionMaster.questionNo": { "$in": myArray }
    }}, 
    { "$project": { 
        "name": 1, 
        "examid": 1, 
        "description": 1, 
        "questionLimit": 1,
        "examDuration": 1, 
        "__v": 1, 
        "questionMaster": {
             "$filter": {
                 "input": "$questionMaster", 
                 "as": "question", 
                 "cond": { 
                     "$setIsSubset": [
                         { "$map": {
                             "input": { "$literal": [ "Q" ] }, 
                             "as": "q", 
                             "in": "$$question.questionNo"
                         }}, 
                         myArray
                     ]
                 }
             }
        }
    }}
])

在MongoDB 3.2之前,您需要使用$match运算符过滤文档。管道中的下一个阶段是$redact阶段,您只能使用$cond表达式检索数组中“questionNo”所在的文档。由于您无法在$in中使用$cond运算符,因此如果您的“questionNo”出现在数组中,则需要使用$setIsSubset运算符返回true。但问题是$setIsSubset需要使用两个数组才能使其工作,您需要使用$map运算符。当然$map输入必须是解析为数组的表达式,因为“questionNo”不是您需要使用$literal运算符的数组。

var myArray = [ "3", "1", "5", "2", "4" ];

db.collection.aggregate([
    { "$match": {
        "examid": "1026",
        "questionMaster.questionNo": { "$in": myArray }
    }},
    { "$redact": {
        "$cond": [
            { "$or": [ 
                { "$setIsSubset": [
                    { "$map": {
                        "input": { "$literal": [ "Q" ] }, 
                        "as": "q", "in": "$questionNo"
                    }},  
                    myArray
                ] }, 
                { "$not": "$questionNo" } 
            ]}, 
            "$$DESCEND", 
            "$$PRUNE" 
        ]
    }}
])