12

I have a schema like this

'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TeacherSchema = new Schema({
    education: [{degree: String, instituteName: String}],
    dob: Date,
    photoUrl: String,
    phoneNumber: String,
    institutes: [{type: mongoose.Schema.ObjectId, ref: 'Institute'}],
    subjects: [{
        name: String,
        topics: [{
            name: String,
            modules: [{
                name: String,
                classes: [{
                    name: String,
                    startTime: Date,
                    endTime: Date,
                    fee: Number
                }]
            }]
        }]
    }],
    created: {type: Date, default: Date.now}
})

module.exports = mongoose.model('Teacher', TeacherSchema);

My question is how can i query in the nested arrays? To be specific Lets say i want to find all the teachers who have at least one subject/topic/module/class whose name starts with "Math". How can i do that with mongoose?

Raghvendra Singh
  • 1,775
  • 4
  • 26
  • 53

1 Answers1

16

See if this works...

db.Teacher.find({$or:
[{'subjects':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics.modules.classes':{"$elemMatch":{'name':'Math'}}}]
})

However, I am curious to know why a modules array is needed when all it contains is a classes array?

Let's say you want to search with wildcard "ath"

db.stack30173606.find({$or: [
{'subjects':{"$elemMatch":{'name':'Math'}}}, 
{'subjects.topics':{"$elemMatch":{'name':'math'}}}, 
{'subjects.topics.modules':{"$elemMatch":{'name':'Math'}}}, 
{'subjects.topics.modules.classes.name':{"$in":[/math/]}}
] })

For case insensitive, check this: How do I make case-insensitive queries on Mongodb?

Community
  • 1
  • 1
  • Thanks. This works but only if the name is equal to what i give. How can i do this for like and case insensitive ?? – Raghvendra Singh May 12 '15 at 20:12
  • i tried that it doesn't work Here is my subject inside teacher "subjects" : [ { "name" : "Mathematics", "topics" : [ { "name" : "math topic", "modules" : [ { "name" : "math module","classes" : [ { "name" : "math class" } ] } ] } ] } ] I have removed some stuff to fit in the comment. Here is my query db.teachers.find({$or: [{'subjects':{"$elemMatch":{'name':'Math'}}}, {'subjects.topics':{"$elemMatch":{'name':'math'}}}, {'subjects.topics.modules':{"$elemMatch":{'name':'Math'}}}, {'subjects.topics.modules.classes':{"$in":[/math/]}}] }); It returns me nothing. – Raghvendra Singh May 12 '15 at 20:42