0

i am strugling with a query that i don't know how to perform... I have two collections,

Tarifas Collection

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 },
})

Now i am using an Aggregation method to retrieve both collection in a response

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

This is working and gives me both collections in the response... but.. In tarifa's collection i have a propertie called 'configs' that is an array with lot of sub collections... this sub collections are a config of each product that i have, So what i need to do is, retrieve all tarifas that has a configs for the product, and if the configs does not contain retrieve the tarifa with a empty array.

Expected result

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

i tried to add $match in my aggregation pipeline.

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

But if there is not any config that match the product it doesn't retrieve the rest of Tarifa's collection

3
  • Can you post please sample data + expected result Commented Mar 18, 2020 at 21:03
  • @Valijon damn, sorry if i am not explaining it well Commented Mar 18, 2020 at 21:30
  • How do you determine that a specific config matches the product or not? Commented Mar 19, 2020 at 1:34

1 Answer 1

1

It seems you are trying to $filter the array after you retrieve it.

This pipeline will return only the configs for which the producto field from the config matches the ref field from the product.

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

    ]

Change the fields in the $eq array to the ones you need to match.

Sign up to request clarification or add additional context in comments.

3 Comments

i think you are really close... but i am doing $$this.producto, which is the field that i am looking inside the tarifas.config array, and i am changing $ref for the data that i want filter... but is not retreiving me config inside the array... it is retreiving with the tarifas agreggation but tarifas.config is empty... and i am checking the collection and there is a register that match with it :S
I tried a lot of ways to find the problem, and it seems that in $filter:{ input: "$tarifas.configs", } is not filtering good, because i tried to filter something up level like $filter:{ input: "$tarifas", cond:{$eq: [""$$this._id, ID] and it is filtering correctly... so why it input: "$tarifas.configs" is not filtering... maybe because configs is an array?.... dunno
ok solved it, just adding the $addFields in the pipeline and it is working... thanks man i am learning a lot about the power of aggregation ;:D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.