具有多个 $match 或 $pipeline 条件的 Mongo $lookup

Posted

技术标签:

【中文标题】具有多个 $match 或 $pipeline 条件的 Mongo $lookup【英文标题】:Mongo $lookup with multiple $match or $pipeline conditions 【发布时间】:2019-10-11 11:02:26 【问题描述】:

我有两个 mongo 集合,一个包含联系人,即患者,另一个包含通知。我正在尝试在给定的 branchId / Clinic_id 中返回所有活动联系人状态的结果:true 并包括他们的确认:错误通知。另外,我想确保联系人显示在结果中,无论他们是否有通知。

我需要通过 branchId aka Clinic_id“加入”集合,然后创建一个包含每个活动联系人未确认通知的数组。

联系人架构:


  patientId:  type: String, required: true ,
  clinic_id:  type: String, required: true ,
  firstName:  type: String, uppercase: true, required: true ,
  lastName:  type: String, uppercase: true, required: true ,
  birthDate:  type: String ,
  phone:  type: String, required: true ,
  status:  type: Boolean, default: true , // true - active patient

通知架构:


  branchId:  type: String, required: true , // aka clinic_id
  patientId:  type: String, required: true ,
  type:  type: String, required: true , // sms, chat, system
  acknowledged:  type: Boolean, default: false ,
  date:  type: Date, default: Date.now 

聚合查询:

[
  
    $match:  clinic_id: '2', status:  $eq: true  
  ,
  
    $lookup: 
      from: 'notifications',
      let:  patient: '$patientId' ,
      pipeline: [
        
          $match: 
            $expr: 
              $and: [
                 $eq: ['$acknowleged', false] ,
                 $eq: ['$patientId', '$$patientId'] 
              ]
            
          
        
      ],
      as: 'notif'
    
  
]

到目前为止,这似乎提供了最好的结果 - 我一直在使用它,然后在节点中过滤结果:

[ 
   $match:  clinic_id: '2', status:  $eq: true   ,
   "$lookup": 
    "from": "notifications",
    "let":  "patientId": "$patientId" ,
    "pipeline": [
       "$match": 
        "$expr":  "$eq": ["$branchId", "2"] ,
        "acknowledged":  "$eq": false 
      
    ],
    "as": "notif"
  
]

我的问题是我要么得到正确的联系人,但在 notif 数组中的条目来自具有相同患者 ID 但分配给另一个 branchId 的患者。或者根据我的尝试,我可能会得到正确的通知数组,但最初的联系人列表将丢失条目。获得所需输出的最佳方法是什么?

我遇到的期望输出和错误输出的示例输出:


  patientId: 1,
  clinic_id: 100,
  firstName: 'John',
  lastName: 'Doe',
  birthDate: '2000-01-01',
  phone: '6665551212',
  status: true,
  notif: [
  
    // This is correct
    branchId: 100, // branchId matches
    patientId: 1,  // patientId matches contacts patientId
    type: 'sms',
    acknowledged: false, // notification is unacknowledged
    date: '2019-05-18T16:18:05.480Z'
  ,
  
   // This is not correct
    branchId: 200, // branchId does not match contacts branchId
    patientId: 1,
    type: 'sms',
    acknowledged: true, // only want acknowledged: false
    date: '2019-05-20T16:18:05.480Z'
  ,
  
   // This is not correct
    branchId: 100, 
    patientId: 2, // PatientId does not match contact
    type: 'sms', 
    acknowledged: false,
    date: '2019-05-20T16:18:05.480Z'
  
  ]

【问题讨论】:

如果有人通过原始聚合查询有轻微的拼写错误来跟踪问题。 “承认”当然应该是“承认”。我编辑的字符不够_ 【参考方案1】:

您需要使用clinicId 再添加一个条件。像这样的

[
   "$match":  "clinic_id": "2", "status":  "$eq": true ,
   "$lookup": 
    "from": "notifications",
    "let":  "patient": "$patientId", "clinic_id": "$clinic_id" ,
    "pipeline": [
       "$match": 
        "$expr": 
          "$and": [
             "$eq": ["$patientId", "$$patientId"] ,
             "$eq": ["$branchId", "$$clinic_id"] 
          ]
        ,
        "acknowleged": false
      
    ],
    "as": "notif"
  
]

【讨论】:

谢谢。我不得不在 let 中将患者更改为 patientId,然后在 match 和 expr 中使用变量 branchId 而不是 $$clinic_id 并且它起作用了。

以上是关于具有多个 $match 或 $pipeline 条件的 Mongo $lookup的主要内容,如果未能解决你的问题,请参考以下文章

Azure pipeline, File matching patterns reference

Azure Pipelines 将 YAML 用于具有不同变量值但没有 YAML 重复的多个环境(阶段)

如何访问 mongoose $aggregate->$lookup-> pipeline->$match 中的字段名称

Apache Pig - 具有多个匹配条件的 MATCHES

五、MongoDB管道——概念篇

Pipeline