Как запросить документ при заполнении его поля документом из другой коллекции в mongoose?

#mongodb #mongoose

#mongodb #mongoose

Вопрос:

У меня есть три схемы, назовите их A, B и C.

Все схемы имеют автоматически сгенерированные _id поля , name , и active . Но C имеет дополнительное поле relations , которое представляет собой объект с двумя полями в нем a_id , и b_id . Что-то вроде этого:

 {
  _id,
  name,
  active,
  relations: {
    a_id,
    b_id
  }
}
 

Что я хотел бы запросить все документы из C, где соответствующие документы A и B оба активны. Поэтому замените идентификаторы: a_id , и b_id фактическими соответствующими документами.

Что-то вроде: C.findMany({ 'relations.a_id': true, 'relations.b_id': true })

Как я могу это сделать?

Ответ №1:

Попробуйте запрос агрегации,

  • $lookup с коллекцией передайте a_id в let в соответствии $match с условием проверки конвейера a_id и активным статусом true
  • $lookup с коллекцией B передайте b_id в let в соответствии $match с условием проверки конвейера b_id и активным статусом true
  • $project чтобы отобразить обязательные поля, $arrayElemAt чтобы получить первый элемент из возвращаемого результата поиска, проверьте, имеет ли он значение null $ifNull , тогда он вернет тот же идентификатор
 C.aggregate([
  {
    $lookup: {
      from: "A",
      let: { id: "$relations.a_id" },
      pipeline: [{
          $match: {
            active: true,
            $expr: { $eq: ["$id", "$_id"] }
          }
      }],
      as: "relations.a_data"
    }
  },
  {
    $lookup: {
      from: "B",
      let: { id: "$relations.b_id" },
      pipeline: [{
          $match: {
            active: true,
            $expr: { $eq: ["$id", "$_id"] }
          }
      }],
      as: "relations.b_data"
    }
  },
  {
    $project: {
      name: 1,
      active: 1,
      relations: {
        a_id: {
          $ifNull: [
            { $arrayElemAt: ["$relations.a_data", 0] },
            "$relations.a_id"
          ]
        },
        b_id: {
          $ifNull: [
            { $arrayElemAt: ["$relations.b_data", 0] },
            "$relations.b_id"
          ]
        }
      }
    }
  }
])
 

Игровая площадка

Комментарии:

1. Если я запускаю игровую площадку (с благодарностью, спасибо), он возвращает только идентификатор для B. Для вас это то же самое? Если нет, то почему?

2. активный статус — false b_id: 2 записи в коллекции B.