Получить пустой массив при использовании конвейера в агрегации поиска MongoDB

#mongodb #pymongo

Вопрос:

У меня есть 2 коллекции, как показано ниже

 collectionA.insertOne({
    cart: [
        { product_id: ObjectId('xxx'), quantity: 10 }
    ]
})
collectionB.insertMany([
    { _id: ObjectId('xxx'), name: '', price: 1 },
    { _id: ObjectId('xyz'), name: '', price: 1 },
])
 

Когда я пытаюсь выполнить поиск по $с помощью внешнего/локального поля, все в порядке

 {
  from: 'collectionB',
  localField: 'cart.product_id',
  foreignField: '_id',
  as: 'product_detail'
}
 

Но я хочу переключиться на использование конвейера, как показано ниже:

 {
  from: 'collectionB',
  let: {pid: '$cart.product_id'},
  pipeline: [
    {
    $match: {
        $expr: {
          $eq: ['$_id', '$pid']
        }
    }
  }],
  as: 'product_detail'
}
 

Затем я получил пустой массив в поле product_detail.
Как я могу сделать так, чтобы это соответствовало моим ожиданиям?

Ответ №1:

При использовании $cart.product_id вы получаете массив со _id значениями, а затем $eq сравниваете идентификатор объекта и массив.

As $in используется для определения того, входит ли значение в массив, который вы должны использовать $in , а $eq не для получения значений, подобных этому примеру.

Результат $lookup такой:

 {
  $lookup: {
    from: "collectionB",
    let: {pid: "$cart.product_id"},
    pipeline: [
      {
        $match: {
          $expr: {
            $in: [ //<--- here use $in
              "$_id",
              "$pid"
            ]
          }
        }
      }
    ],
    as: "product_detail"
  }
}