The solution is sound, but your schema is at fault here. There are big problems with using "named keys" with a database like this, and you should consider them as "attributes" instead.
Such as in:
{
"_id" : ObjectId("559a7353186a384b54f9aea9"),
"attendance" : [
{
"date" : ISODate("2015-12-17T00:00:00Z"),
"student" : ObjectId("558febdb949eff4711e621e9")
},
{
"date" : ISODate("2015-12-17T00:00:00Z"),
"student" : ObjectId("559020fe79f141941ddd3246")
},
{
"date" : ISODate("2015-11-14T00:00:00Z"),
"student" : ObjectId("558febdb949eff4711e621e9")
},
{
"date" : ISODate("2015-11-14T00:00:00Z"),
"student" : ObjectId("559020fe79f141941ddd3246")
}
]
}
Which would be defined in a schema as:
AttendanceSchmema = new Schema({
"date": Date,
"student": { "type": Schema.Types.ObjectId, "ref": "Student" }
},{ "_id": false });
CourseSchema = new Schema({
"attendance": [AttendanceSchema]
});
Then I can simply match for as given student:
Course.find(
{ "attendance.student": "559020fe79f141941ddd3246" },
{ "attendance.$": 1 }
)
Or even a student on a given date:
Course.find(
{ "attendance": {
"$elemMatch": {
"student": "559020fe79f141941ddd3246",
"date": { "$gte": new Date("2015-12-15"), "$lt": new Date("2015-12-16") }
}
}},
{ "attendance.$": 1 }
)
And even more possibilities in between. The reason we put all of this in a single array with "attribute" like properties is to make it simple to query and store.
Without such a change, you are stuck with horribly performing queries like:
Course.find({ "$where": function() {
return Object.keys(this.attendance).some(function(k) {
return this.attendance[k].indexOf("558febdb949eff4711e621e9") > -1
});
}})
Presuming of course that those values are presently "strings", as they would appear to be by the Mixed type.
And even worse queries for anything more complex, which also cannot tell you which position was matched. But by far the worst thing is these cannot possibly use an "index" in order to match.
Therefore you really should consider changing the database schema here to a form that is going to support querying in the most efficient way.
"2015-12-17"which get in the way of things like the referenced solution being useful. Your schema design choice is therefore at fault. If you change the schema then you can do exactly what you want in an efficient way. Right now, the only ways are not very efficient at all.