You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询:如何将InspectionItemNotes匹配到对应InspectionItem

问题:InspectionItem与对应InspectionItemNotes关联匹配错误

当前尝试将InspectionItemNotes中的笔记与对应的InspectionItem关联时,出现归属错误:"Water"条目关联了"Fire note 1","Fire"条目关联了"Water note 1",期望每个检查项仅关联属于自己的笔记。

数据集

Inspections集合

{  
  "_id": {"$oid": "635c37d00017b0adec605f01" },  
  "REF_InspectionItems": [    
    {"$oid": "635c37d30017b0adec605f1d" },    
    {"$oid": "635c37d60017b0adec605f34" }  
  ]
}

InspectionItems集合

[  
  {    
    "_id": {"$oid": "635c37d30017b0adec605f1d"},    
    "name": "Water",    
    "REF_InspectionItemNotes": [      
      {"$oid": "635c37d40017b0adec605f26" },      
      {"$oid": "635c37d50017b0adec605f2c" }    
    ]  
  },  
  {    
    "_id": {"$oid": "635c37d60017b0adec605f34"},    
    "name": "Fire",    
    "REF_InspectionItemNotes": [      
      {"$oid": "635c37d70017b0adec605f3d" }    
    ]  
  }
]

InspectionItemNotes集合

[  
  {    
    "_id": {"$oid": "635c37d40017b0adec605f26"},    
    "text": "Water note 1"  
  },  
  {    
    "_id": {"$oid": "635c37d50017b0adec605f2c"},    
    "text": "Water note 2"  
  },  
  {    
    "_id": {"$oid": "635c37d70017b0adec605f3d"},    
    "text": "Fire note 1"  
  }
]

尝试的聚合管道

[  
  {    
    '$lookup': {      
      'from': 'inspectionitems',       
      'localField': 'REF_InspectionItems',       
      'foreignField': '_id',       
      'as': 'inspectionItemsLookup'    
    }  
  }, {    
    '$lookup': {      
      'from': 'inspectionitemnotes',       
      'localField': 'inspectionItemsLookup.REF_InspectionItemNotes',       
      'foreignField': '_id',       
      'as': 'inspectionItemNotesLookup'    
    }  
  }, {    
    '$project': {      
      'items': {        
        '$map': {          
          'input': '$inspectionItemsLookup',           
          'as': 'temp',           
          'in': {            
            '$mergeObjects': [              
              '$$temp', {                
                'notes': {                  
                  '$map': {                    
                    'input': '$inspectionItemNotesLookup',                    
                    'as': 'temp2',                    
                    'in': {                      
                      '$mergeObjects': [                        
                        '$$temp2', {                          
                          'thisIsNotShowingUp': {                            
                            '$first': {                              
                              '$filter': {                                
                                'input': '$inspectionItemNotesLookup',                                
                                'cond': {                                  
                                  '$eq': [                                    
                                    '$$temp2.REF_InspectionItemNotes', '$$this._id'                                  
                                ]                                
                              }                              
                            }                            
                          }                        
                        }                      
                      ]                    
                    }                  
                  }                
                }              
              }            
            ]          
          }        
        }      
      }    
    }  
  }
]

解决方案

原管道的问题在于第二个$lookup将所有关联的笔记一次性查询到一个数组中,后续$map时未根据当前检查项的REF_InspectionItemNotes过滤对应笔记,导致所有笔记被错误关联给每个检查项。

以下是修正后的聚合管道,通过分步关联确保每个检查项仅匹配自己的笔记:

[
  // 第一步:关联InspectionItems
  {
    '$lookup': {
      'from': 'inspectionitems',
      'localField': 'REF_InspectionItems',
      'foreignField': '_id',
      'as': 'inspectionItemsLookup'
    }
  },
  // 第二步:拆分每个检查项,为单独关联笔记做准备
  {
    '$unwind': '$inspectionItemsLookup'
  },
  // 第三步:针对每个检查项,关联对应的笔记
  {
    '$lookup': {
      'from': 'inspectionitemnotes',
      'let': { 'noteIds': '$inspectionItemsLookup.REF_InspectionItemNotes' },
      'pipeline': [
        { '$match': { '$expr': { '$in': ['$_id', '$$noteIds'] } } }
      ],
      'as': 'inspectionItemsLookup.notes'
    }
  },
  // 第四步:将拆分的检查项重新组合为数组
  {
    '$group': {
      '_id': '$_id',
      'items': { '$push': '$inspectionItemsLookup' }
    }
  }
]

管道说明

  1. 先通过$lookup关联所有目标InspectionItems;
  2. 使用$unwind将InspectionItems数组拆分为单个文档,便于后续逐个关联笔记;
  3. 再次使用$lookup,通过let传递当前检查项的笔记ID列表,在子管道中用$match匹配对应的笔记,将结果存入当前检查项的notes字段;
  4. 最后用$group将拆分的检查项重新组合为数组结构,得到每个检查项关联自身笔记的结果。

内容的提问来源于stack exchange,提问作者MrLister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:01:07