Prasanga Thapaliya
Prasanga Thapaliya

Reputation: 727

Filtering documents in mongodb and nodejs

Data in the database is stored as given below. if I do a query like

const food = await Nutrition.find()

Then I get this in response

[
  {
    _id: 6035ff4778b1893fa5e8080f,
    name: 'apple',
    weight: 100,
    unit: 'gram',
    carbohydrates: 14,
    calories: 52,
    proteins: 0.3,
    fats: 0.2,
    __v: 0
  },
  {
    _id: 6036011437035541b0bd5e0a,
    name: 'banana',
    weight: 100,
    unit: 'gram',
    carbohydrates: 23,
    calories: 89,
    proteins: 11,
    fats: 0.39,
    __v: 0
  },
  {
    _id: 6036011437035541b0bd5e0b,
    name: 'melon',
    weight: 100,
    unit: 'gram',
    carbohydrates: 45,
    calories: 100,
    proteins: 11,
    fats: 0.39,
    __v: 0
  }
]

I have this controller in nodejs which fetch food nutrition from the database

const Nutrition = require('../model/nutritionalFacts')

exports.nutritionFacts = (async (req,res) =>{
    try {
        const food = await Nutrition.find()
        console.log(food);
    } catch (error) {
        console.log('Error occurred',error.message);
    }
})

Now in request (req), req.body is coming as

[
  { name: 'apple', id: 0, selected: true, weight: 100, unit: 'gram' },
  { name: 'banana', id: 1, selected: true, weight: 100, unit: 'gram' }
]

Now I want to filter only those documents from the database whose name matches with the name coming in an array of objects from the client as mentioned above without looping, just using MongoDB query syntax. Can we do this?

Upvotes: 0

Views: 669

Answers (2)

Dheemanth Bhat
Dheemanth Bhat

Reputation: 4452

Try this

const Nutrition = require('../model/nutritionalFacts');

exports.nutritionFacts = (async (req, res) => {
  try {

    if (!Array.isArray(req.body.payload)) {
      throw new Error("Invalid payload!") // or whatever error message u want!
    }

    const names = payload.map(item => item.name); // u cannot avoid this looping of payload!

    const conditions = {
      name: { $in: names }
    };

    const food = await Nutrition.find(conditions);
    console.log(food);
  } catch (error) {
    console.log('Error occurred', error.message);
  }
})

Upvotes: 1

Ali Can
Ali Can

Reputation: 574

You can use $in operator to achieve that. You need to change your find method as below

var namesArr = ["banana", "melon"];
db.Nutrition.find({ "name" : { "$in": namesArr } })

Then the results for the sample above:

{
        "_id" : ObjectId("60361058cce08c8b8ebe0509"),
        "name" : "banana",
        "weight" : 100,
        "unit" : "gram",
        "carbohydrates" : 23,
        "calories" : 89,
        "proteins" : 11,
        "fats" : 0.39,
        "__v" : 0
}
{
        "_id" : ObjectId("60361058cce08c8b8ebe050a"),
        "name" : "melon",
        "weight" : 100,
        "unit" : "gram",
        "carbohydrates" : 45,
        "calories" : 100,
        "proteins" : 11,
        "fats" : 0.39,
        "__v" : 0
}

Upvotes: 1

Related Questions