iMSn20
iMSn20

Reputation: 255

Find documents by reference property (not id)

I want to find all the products who belong to a category recived in an array, i.e.

I have this documents of category:

{
    "_id" : ObjectId("5fa006c9e8c8633bd00dc9bf"),
    "name" : "Beer"
    "__v" : 0
}

{
    "_id" : ObjectId("5fa3f6a69a55a4294815d333"),
    "name" : "Gin"
    "__v" : 0
}

And three products like this:

{
    "_id" : ObjectId("5fc5ba87d5b8e358888e976f"),
    "code" : "CER473HEIN",
    "category" : ObjectId("5fa006c9e8c8633bd00dc9bf"),
    "__v" : 0
}

{
    "_id" : ObjectId("6011e4d83408972b34fd048f"),
    "code" : "GIN700BEEF",
    "category" : ObjectId("5fa3f6a69a55a4294815d333"),
}

{
    "_id" : ObjectId("6011e4f73408972b34fd0492"),
    "code" : "GIN700GORD",
    "category" : ObjectId("5fa3f6a69a55a4294815d333"),
}

If in the body of the request I send an array like this:

{ categories = ['Beer', 'Gin']` }

I want to get all three products but if I only send 'Beer' I want to get only the product with the category 'Beer'.

I was trying something like this in the service layer of Product:

let getProductsByCategories = (req, res) => {
    const { categories } = req.body; 
    Product.find({ 'category.name' : { $in: categories }})
        .exec((err, productos) => {
            if (err) {
                return res.status(500).json({
                    ok: false,
                    error: 'Error interno en el servidor'
                });
            }
            if (!productos) {
                return res.status(400).json({
                    ok: false,
                    error: {
                        message: 'No se encontraron productos.'
                    }
                });
            }

            res.json({
                ok: true,
                cantidad: productos.length,
                entidadResultante: productos
            });
        })
}

I.E:

But it always return 0 products with a category who was 6 products. Any idea why this is happening? Ty.

Upvotes: 0

Views: 57

Answers (1)

Mohammad Yaser Ahmadi
Mohammad Yaser Ahmadi

Reputation: 5051

you can using populate if you used ref in schema, but without ref you should write two query, at first get list of Id's category based on req.body.categories after that you can get the list of products

 let getProductsByCategories = (req, res) => {
    const { categories } = req.body; 
    Category.find({ 'category.name' : { $in: categories }})
        .exec((err, categoryID) => {
            if (err) {
                return res.status(500).json({
                    ok: false,
                    error: 'Error interno en el servidor'
                });
            }
            if (!categoryID) {
                return res.status(400).json({
                    ok: false,
                    error: {
                        message: 'categoryID'
                    }
                });
            }
            let listOfIds = categoryID.map(item => item._id)
            Product.find({ 'category' : { $in: listOfIds }})
            .exec((err, productos) => {
                res.json({
                    ok: true,
                    cantidad: productos.length,
                    entidadResultante: productos
                });
            })

        })
}

if you are using ref in schema, just try like this:

  Product.find()
    .populate({
      path: "category",
      match: {
        "category.name": { $in: categories },
      },
    })
    .exec(function (err, productos) {
      console.log(productos);
    });
};

Upvotes: 1

Related Questions