chris_
chris_

Reputation: 93

Mongoose find with multiple and optional fields

I am new to mongoose and currently I am coding an app to learn it. I have an Artist Schema and a form that search with multiple and optional fields. For instance the user can put a name, a minimum age and search through the model without filling the other form fields.

On the controller I take all the fields from the form through the req.body object and I have a query object which with multiple if statements I check whether or not the property is not undefined, and if not I put it in the object as a property and the object is passed to the find method.

The problem is when I fill the min age and put to the query object this property query.min_age = { $gte: min_age} the $gte converts into a string and as a result can't run the find method properly.

The Mongoose Model

const mongoose = require("mongoose");
const AlbumSchema = require("./album")
const CompanySchema = require("./company")

const Schema = mongoose.Schema;

const ArtistSchema = new Schema({
    name: String,
    age: Number,
    yearsActive: Number,
    albums: [AlbumSchema],
    company:[{type: Schema.Types.ObjectId, ref: "Company"}]
});

const Artist = mongoose.model("artist", ArtistSchema);

module.exports = Artist;

The Controller

app.post("/", (req, res, next) => {
    const name = req.body.name;
    const min_age = req.body.min_age;
    const min_active = req.body.min_active;
    const sort = req.body.sort;
    const query = {};

    if(name) {
        query.name = name;
    }

    if(min_age) {
        query.min_age = { $gte: min_age};
    }

    if(min_active) {
        qyery.min_active = {gte: min_active};
    }

    Artist.find(query).
    sort(sort)
    .then( artists => {
         res.render("index", {
             artists: artists
        })
    });
});

The image below is depicting the string $gte when I console it:
The image below is depicting the string $gte when I console it

Upvotes: 0

Views: 661

Answers (2)

Dhaval Italiya
Dhaval Italiya

Reputation: 449

const name = new RegExp(req.body.name, 'i');
const min_age = req.body.min_age;
const min_active = req.body.min_active;
const sort = req.body.sort;
const query = {};

if(req.body.name!=undefined && req.body.name!=''){
   query["$and"]=[{name :re}]
}
if(min_age){
   query["$and"].push({min_age:{ $gte: parseInt(min_age)}})
}
if(min_active ){
   query["$and"].push({min_active:{ $gte: parseInt(min_active)}})
}
let artists=await Artist.find(query).sort(sort)

res.render("index", {
  artists: artists
})

Upvotes: 0

jjanczyk
jjanczyk

Reputation: 481

Keys in JS objects are always casted to a string, so there is nothing wrong with $gte being a string on a screenshot that you've posted.

As for the min_age value, in your code I cannot see anything that would convert it to a string and mongoose by itself is not doing it as well.

It looks like the problem is in a test request. Please check if you are sending min_age as a number in a POST request, or as a string. It should be a number or else you need to convert it to a number in your controller (with parseInt() for example)

Upvotes: 1

Related Questions