Проблема с использованием агрегации в mongodb при получении данных из двух коллекций - PullRequest
0 голосов
/ 19 марта 2020

Я борюсь с запросом, который я не знаю, как выполнить ... У меня есть две коллекции,

Тарифная коллекция

tarifaConfig = new Schema({
    producto: { type: String },
    titulo: { type: String },
    bloqueo: { type: Boolean },
    margen: { type: Number },
    precioVenta: { type: Number },
    precioVentaIva: { type: Number },
})

const tarifaSchema = new Schema({
    codigo: { type: String },
    titulo: { type: String },
    margen: { type: Number },
    estado: { type: Boolean },
    bloqueo: { type: Boolean },
    configs: [tarifaConfig]
})

Producto Collection

const productosSchema = new Schema({
    ref: { type: String },
    nombre: { type: String },
    precioCompra: { type: Number },
    precioCompraIva: { type: Number },
    precioVenta: { type: Number },
    precioVentaIva: { type: Number },
    iva: { type: Number },
})

Теперь я использую метод агрегации для получения обеих коллекций в ответе

 productosModel.aggregate([
        {
            $match: { _id: ObjectId(req.params.id) }
        },
        {
            $lookup: {
                from: "tarifas",
                as: "tarifas",
                pipeline: []
            }
        }
    ]).then((producto) => {
        res.json(producto);
    })

Это работает и дает мне обе коллекции в ответе ... но .. В коллекции Тарифы у меня есть свойство ie, называемое 'configs', которое представляет собой массив с множеством подколлекций ... Эти подколлекции являются конфигурацией каждого продукта, который у меня есть, так что мне нужно сделать, получить все тарифы, которые имеют конфиги для продукта, и если конфиги не содержат, получить тарифа с пустым массивом.

Ожидаемый результат

{
   ref: 'rbe34',
   nombre: 'bike',
   precioCompra: 10,
   precioCompraIva: 12.1,
   precioVenta: "",
   precioVentaIva: "",
   iva: 21,
   tarifas:[
   { 
    codigo: 'NOR',
    titulo: 'Normal tarifa',
    margen: 33,
    estado: true,
    bloqueo: true,
    configs: [], ///HERE I NEED A EMPTY ARRAY IF THERE IS NOT ANY CONFIG THAT MATCH WITH THE PRODUCT ID,  
   }
   ]
}

Я пытался добавить $ match в свой конвейер агрегации.

   productosModel.aggregate([
        {
            $match: { _id: ObjectId(req.params.id) }
        },
        {
            $lookup: {
                from: "tarifas",
                as: "tarifas",
                pipeline: [
                    { $match: { 'configs.producto': req.params.id } }
                ]
            }
        }
    ])

Но если нет конфигурации, соответствующей продукту, он не получает остальную часть коллекции Tarifa

1 Ответ

1 голос
/ 19 марта 2020

Кажется, вы пытаетесь $filter массив после его получения.

Этот конвейер будет возвращать только те конфиги, для которых поле producto из конфигурации совпадает с полем ref из товар.

    [
        {
            $match: { _id: ObjectId(req.params.id) }
        },
        {
            $lookup: {
                from: "tarifas",
                as: "tarifas",
                pipeline: [
                  {
                    $addFields: {
                         "tarifas.configs":{ $filter:{
                                               input: "$tarifas.configs",
                                                cond: {$eq:["$$this.producto","$ref"]}
                           } }
                       } 
                   }
               ]
            }
        },

    ]

Измените поля в массиве $eq на те, которые вам нужны.

...