Конвейер Mongo $ lookup $ с несколькими параметрами $ expr не возвращает правильные данные в результатах $ lookup - PullRequest
0 голосов
/ 25 мая 2019

У меня есть две коллекции монго, одна из которых содержит напоминания о встречах, а другая содержит уведомления.Я пытаюсь вернуть результаты со всем архивом: ложные напоминания в заданном BranchId / clinic_id и включить их подтвержденные: ложные уведомления.Кроме того, я хочу убедиться, что встречи отображаются в результатах независимо от того, есть ли у них уведомления или нет.

Мне нужно «объединить» коллекции с помощью branchId aka clinic_id, а затем создать массив любых неподтвержденных уведомлений длякаждое полученное напоминание о встрече.

Я возвращаю правильные встречи , но массив уведомлений не фильтруется путем сопоставления PatientId / Patient_id.Кажется, что каждое напоминание содержит одинаковый массив уведомлений.Кроме этого все остальное кажется правильным.Итак, мой вопрос как я могу убедиться, что массив уведомлений содержит только PatientID, который соответствует значению Patient_id напоминания?

Схема напоминания усеченного назначения:

      {
      time: {
        type: Date,
        required: true
      },
  patient_id: {
    type: String,
    required: true
  },
      status: {
        type: String,
        default: 'unconfirmed'
      },
      archive: {
        type: Boolean,
        default: false
      },
      branch: [
    // Incorrectly setup as an array rather than an object. 
    // Can $unwind as there is only ever one item in the array
        {
          name: {
            type: String,
            required: true
          },
          clinic_id: { // aka branchId
            type: String,
            required: true
          }
        }
      ]
    }

Схема уведомлений:

{
  branchId: { type: String, required: true }, // aka clinic_id
  patientId: { type: String, required: true },
  acknowledged: { type: Boolean, default: false },
  date: { type: Date, default: Date.now }
}

Запрос агрегации:

[
  { $match: { 'branch.0.clinic_id': '1', archive: false } },
  { $unwind: '$branch' },
  {
    $lookup: {
      from: 'notifications',
      let: { clinic_id: '1', patient_id: '$patientId' }, //<-- issue with patient_id?
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
               { $eq: ["$patientId", "$$patientId"] }, <-- errors $$patientId unknown value. $$patient_id returns 0 results.
                { $eq: ['$branchId', '$$clinic_id'] },
                { $eq: ['$acknowledged', false] }
              ]
            }
          }
        }
      ],
      as: 'notif'
    }
  }
]

Пример вывода с комментариями по желаемому выводу и неправильным выводом, с которыми я столкнулся:

  {
  patient_id: '1',
  time: '2019-05-29T11:00:00.000Z',
  status: 'unconfirmed',
  archive: false,
  branch: [
    {
      name: 'Example location',
      clinic_id: '100',
    }
  ],
  notif: [
  {
    // This is correct
    branchId: '100', // branchId matches clinic_id
    patientId: '1',  // patientId matches contacts patient_id
    acknowledged: false, // notification is unacknowledged
    date: '2019-05-18T16:18:05.480Z'
  },
  {
   // This is not correct
    branchId: '100', 
    patientId: '2', // PatientId does not match patient_id of reminder
    acknowledged: false,
    date: '2019-05-20T16:18:05.480Z'
  }
  ]
}

Ответы [ 2 ]

1 голос
/ 26 мая 2019

Сначала вы должны использовать $$patient_id, это правильный синтаксис для использования переменной поиска.

Причиной, по которой вы получаете 0 результатов с правильным синтаксисом, является (я предполагаю, что вы не предоставили полную схему) тип отличается.

Обратите внимание, что в вашей схеме уведомлений указано patientId:

patientId: { type: String, required: true }, который набирается String.

Из "желаемой" схемы вывода, которую вы указали в конце:

{ patientId: 1, ... }

Похоже, ваш PatientId определен как Число, поэтому причина не совпадает между документами.

0 голосов
/ 26 мая 2019

С помощью Тома Слаббэрта это решило проблему:

[
        { $match: { 'branch.clinic_id': '1', archive: false } },
        { $unwind: '$branch' },
        {
          $lookup: {
            from: 'notifications',
            let: { clinic_id: '1', patient_id: '$patient_id' }, // <-- changed here
            pipeline: [
              {
                $match: {
                  $expr: {
                    $and: [
                      { $eq: ["$$patient_id", "$patientId"]}, // <-- changed here
                      { $eq: ['$branchId', '$$clinic_id'] },
                      { $eq: ['$acknowledged', false] }
                    ]
                  }
                }
              }
            ],
            as: 'notif'
          }
        }
      ]
...