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

标签 javascript node.js mongodb mongoose aggregation-framework

我有两个 mongo 集合,一个包含联系人,也就是患者,另一个包含通知。我正在尝试返回所有事件联系人状态的结果:在给定的 branchId/clinic_id 中为 true 并包括他们的 acknowledged: false 通知。此外,我想确保联系人显示在结果中,无论他们是否有通知。

我需要通过 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'
    }
  }
]

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

[ 
  { $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 的患者的条目。或者根据我的尝试,我可能会得到正确的 notif 数组,但最初的联系人列表将缺少条目。获得所需输出的最佳方式是什么?

示例输出以及我遇到的期望输出和不正确输出的注释:

{
  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'
  }
  ]
}

最佳答案

您需要使用 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"
  }}
]

关于javascript - 具有多个 $match 或 $pipeline 条件的 Mongo $lookup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56299478/

相关文章:

c# - UnityWebRequest.downloadHandler 返回 null,同时从 Node 服务器获取响应

javascript - 使用 grunt 更新我的 css 文件

javascript - Angular.js 将一个属性绑定(bind)到另一个

Netbeans 中的 JavaScript

javascript - 在 React 中映射从 Nodejs 接收的数组时出现问题

python - 混合 PostgreSQL 和 MongoDB(作为 Django 后端)

javascript - jQuery Autogrow 和 Autosize - 它们不适用于我的输入

mysql - Node orm2 套接字集成

node.js - Puppeteer 等待目标框架 Ubuntu digitalocean

javascript - 自动递增序列字段错误 - MongoDB、Mongoose