从 mongoose 的子数组中找到匹配多个对象的记录

Posted

技术标签:

【中文标题】从 mongoose 的子数组中找到匹配多个对象的记录【英文标题】:find the record with the matching multiple objects from sub array in mongoose 【发布时间】:2022-01-23 18:59:20 【问题描述】:

数据库中存储的数据: 如何获取匹配多个子数组对象的记录sub_question


    "_id": "61c1c0efc204bb170e280d2f",
    "title": "Searching Relevant Cases",
    "question": "Your Industry",
    "vendor_id": "61b8324040fb21d80f3e6702",
    "answer_type": "is_radio",
    "optional_answer": false,
    "sub_question_type": "none",
    "answers": [
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c0efc204bb170e280d30",
            "answer": "Bank"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c0efc204bb170e280d31",
            "answer": "Tech"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c0efc204bb170e280d32",
            "answer": "Other"
        
    ],
    "view": "list_view",
    "is_active": true,
    "is_delete": false,
    "sub_question": [],
    "draggable_list": [],
    "__v": 0
,

    "_id": "61c1c142c204bb170e280d45",
    "title": "Searching Relevant Cases",
    "question": "Employee size",
    "vendor_id": "61b8324040fb21d80f3e6702",
    "answer_type": "is_radio",
    "optional_answer": false,
    "sub_question_type": "none",
    "answers": [
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c142c204bb170e280d46",
            "answer": "SMB (<100)"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c142c204bb170e280d47",
            "answer": "Mid (100 - 1000)"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c142c204bb170e280d48",
            "answer": "Enterprise (> 1000)"
        
    ],
    "view": "list_view",
    "is_active": true,
    "is_delete": false,
    "sub_question": [],
    "draggable_list": [],
    "__v": 0
,

    "_id": "61c1c24ac204bb170e280d5e",
    "title": "Dependent",
    "question": "On previous Chosen option",
    "vendor_id": "61b8324040fb21d80f3e6702",
    "answer_type": "is_radio",
    "optional_answer": false,
    "sub_question_type": "has_parent",
    "sub_question": [
        
            "question_id": "61c1c0efc204bb170e280d2f",
            "_id": "61c1c24ac204bb170e280d5f",
            "answer": "Bank"
        ,
        
            "question_id": "61c1c142c204bb170e280d45",
            "_id": "61c1c24ac204bb170e280d60",
            "answer": "SMB (<100)"
        
    ],
    "answers": [
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d61",
            "answer": "answer 1"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d62",
            "answer": "answer2"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d63",
            "answer": "answer3"
        
    ],
    "view": "list_view",
    "is_active": true,
    "is_delete": false,
    "draggable_list": [],
    "__v": 0
,

    "_id": "61c1c2d7c204bb170e280d7e",
    "title": "Dependent 1",
    "question": "On previous Chosen option 1",
    "vendor_id": "61b8324040fb21d80f3e6702",
    "answer_type": "is_radio",
    "optional_answer": false,
    "sub_question_type": "has_parent",
    "sub_question": [
        
            "question_id": "61c1c142c204bb170e280d45",
            "_id": "61c1c2d7c204bb170e280d7f",
            "answer": "Mid (100 - 1000)"
        ,
        
            "question_id": "61c1c0efc204bb170e280d2f",
            "_id": "61c1c2d7c204bb170e280d80",
            "answer": "Tech"
        
    ],
    "answers": [
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c2d7c204bb170e280d81",
            "answer": "answer 11"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c2d7c204bb170e280d82",
            "answer": "answer 22"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c2d7c204bb170e280d83",
            "answer": "answer 33"
        
    ],
    "view": "list_view",
    "is_active": true,
    "is_delete": false,
    "draggable_list": [],
    "__v": 0

根据 question_id 和 answer 查询以找到所需的结果:


    "obj": 
        "question_id": "61c1c0efc204bb170e280d2f",
        "answer": "Bank"
    ,
    "obj1": 
        "question_id": "61c1c142c204bb170e280d45",
        "answer": "SMB (<100)"
    

想要达到的结果:


    "_id": "61c1c24ac204bb170e280d5e",
    "title": "Dependent",
    "question": "On previous Chosen option",
    "vendor_id": "61b8324040fb21d80f3e6702",
    "answer_type": "is_radio",
    "optional_answer": false,
    "sub_question_type": "has_parent",
    "sub_question": [
        
            "question_id": "61c1c0efc204bb170e280d2f",
            "_id": "61c1c24ac204bb170e280d5f",
            "answer": "Bank"
        ,
        
            "question_id": "61c1c142c204bb170e280d45",
            "_id": "61c1c24ac204bb170e280d60",
            "answer": "SMB (<100)"
        
    ],
    "answers": [
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d61",
            "answer": "answer 1"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d62",
            "answer": "answer2"
        ,
        
            "is_rating": false,
            "is_specific_date": false,
            "_id": "61c1c24ac204bb170e280d63",
            "answer": "answer3"
        
    ],
    "view": "list_view",
    "is_active": true,
    "is_delete": false,
    "draggable_list": [],
    "__v": 0

【问题讨论】:

【参考方案1】:
    $objectToArray 将 userInput 转换为 k-v 元组数组以便于处理 $map 检查question_id 是否为$in sub_question 数组 $match$allElementsTrue
db.collection.aggregate([
  
    "$addFields": 
      "userInput": 
        "obj": 
          "question_id": "61c1c0efc204bb170e280d2f",
          "answer": "Bank"
        ,
        "obj1": 
          "question_id": "61c1c142c204bb170e280d45",
          "answer": "SMB (<100)"
        
      
    
  ,
  
    "$addFields": 
      "userInput": 
        "$objectToArray": "$userInput"
      
    
  ,
  
    "$addFields": 
      "userInput": 
        "$map": 
          "input": "$userInput.v",
          "as": "q",
          "in": 
            $and: [
              
                "$in": [
                  "$$q.question_id",
                  "$sub_question.question_id"
                ]
              ,
              
                "$in": [
                  "$$q.answer",
                  "$sub_question.answer"
                ]
              
            ]
          
        
      
    
  ,
  
    "$match": 
      $expr: 
        $eq: [
          true,
          
            "$allElementsTrue": [
              "$userInput"
            ]
          
        ]
      
    
  
])

这里是Mongo playground 供您参考。

【讨论】:

它返回两个对象。在我的情况下,我只想要一个同时匹配 obj 和 obj1 的对象。 @MunamRamay 很抱歉这个错误。更新了答案以匹配 question_idanswer

以上是关于从 mongoose 的子数组中找到匹配多个对象的记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mongoose 从 JSON 对象数组中查询具有匹配 ID 的集合

Mongoose:如何从对象数组中查找多个字段

将新对象插入到 mongoose 中的子文档数组字段中

将新对象插入到 mongoose 中的子文档数组字段中

在子数组猫鼬中找到只有匹配对象的对象数组?

发送多个子文档时,Mongoose 验证失败