1

I am having some trouble using model.find to return a list of documents that match a variable condition within my nested schema. I am using node, express, and mongoose for this project.

Ideally I want to use a variable as the object key within the query so I can dynamically grab the day of the week and check the open hours. I haven't had any success so far in finding an answer for this online.

Here is my model.

const restaurantSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: { type: String, required: true },
    coordinates: {
        latitude: { type: Number, required: true },
        longitude: { type: Number, required: true }
    },
  happy_hour: {
      sunday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      monday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      tuesday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      wednesday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      thursday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      friday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      saturday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      }
  }
});

Here is a snippet from the controller that is handling the logic for this express route. The snippet below has a static key called "Friday", but I want to dynamically get the day of the week and pass that in as a variable, something like $friday: { open: true } or what not.

exports.search = (req, res, next) => {
    const radius = req.query.radius || 5;
    const latitude = req.query.latitude;
    const longitude = req.query.longitude;
    const day = date.get_day();
    const minutes = date.get_minutes();
    console.log(query[day]);
    if ( latitude == undefined || longitude == undefined ) {
        res.status(404).json({
            message: "Missing longitude or latitude"
        })
    }
    Restaurant.find({ 
        hours: {
            friday: {
                open: true
            }
        }
    })
        .exec()
        .then(results => {
            res.status(200).json({
                data: results.map( result => {
3
  • Probably you can build the query as a string (using string interpolation) and then parse it as JSON: query = JSON.parse("{hours: {``$day``: {open: true}}}") Commented Apr 18, 2018 at 7:55
  • I am not familiar with the syntax $day in that statement. How does that work? Commented Apr 18, 2018 at 18:38
  • It is "String interpolation" developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Apr 19, 2018 at 14:04

2 Answers 2

2

You can try this

var day = req.params.dayName;
var query = {};
query["hours"] = {[day] :true};
collection.find(query, function (err, item) { ... });
Sign up to request clarification or add additional context in comments.

2 Comments

I had to change the query to {[day]: { open: true }} to work with my example above, but with that said the query returns the same structure as my schema with correct day, however, the query is returning no results. I definitely have some data in mongo that should be returned for this query. Any ideas? I noticed that the day was capitalized so I set it to lowercase and it had no effect.
console.log is showing the query as { hours: { wednesday: { open: true } } } which is correct. I have restaurants in the database which have this set to true.
1

You have multiple options to do that.

The query that mongoose expects, is just an object.

const query = { hours : {} };
hours[getTheCurrentDay()].open = true;

// Or with es6

const query = { hours : { [getTheCurrentDay()] : { open : true } };

// Or with pure string

const query = { `hours.${getTheCurrentDay()}.open` : true };

Restaurant.find( query ).exec()...

2 Comments

Are there any performance benefits to using any of these options?
Without making any perfs, I would say insignificant performance difference. What you should ask yourself though is which one is more readable for your code base.

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.