ソリューションは、音ですが、あなたのスキーマがここに障害があります。このようなデータベースで「名前付きキー」を使用することには大きな問題があります。その代わりに、それらを「属性」とみなす必要があります。
ようなのように:として、スキーマで定義されるであろう
{
"_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")
}
]
}
:
Course.find(
{ "attendance.student": "559020fe79f141941ddd3246" },
{ "attendance.$": 1 }
)
あるいは:
AttendanceSchmema = new Schema({
"date": Date,
"student": { "type": Schema.Types.ObjectId, "ref": "Student" }
},{ "_id": false });
CourseSchema = new Schema({
"attendance": [AttendanceSchema]
});
それから私は、単に与えられたとして、学生のために一致させることができます所与の日付の学生:
Course.find(
{ "attendance": {
"$elemMatch": {
"student": "559020fe79f141941ddd3246",
"date": { "$gte": new Date("2015-12-15"), "$lt": new Date("2015-12-16") }
}
}},
{ "attendance.$": 1 }
)
さらに多くの可能性があります。このようにすべてを属性のような属性を持つ単一の配列に入れる理由は、クエリと格納を簡単にするためです。このような変更がなければ
、あなたはのような恐ろしくクエリの実行で立ち往生している:
Course.find({ "$where": function() {
return Object.keys(this.attendance).some(function(k) {
return this.attendance[k].indexOf("558febdb949eff4711e621e9")
});
}})
彼らはMixed
タイプであるように思われるよう、これらの値は、現在、「文字列」であることを当然の前提。
また、より複雑なものについてはさらに悪い質問があり、どの位置が一致したかは分かりません。しかし、最悪のことは、これらが一致するためにおそらく「インデックス」を使用できないことです。
したがって、ここでデータベーススキーマを最も効率的な方法でクエリをサポートするフォームに変更することを検討する必要があります。
ここで問題となるのは、2015-12-17 "のような"名前付きキー "があり、参照されている解決策のように役立つということです。したがって、スキーマ設計の選択に誤りがあります。スキーマを変更すると、効率的な方法で必要なものを正確に行うことができます。今、唯一の方法はあまり効率的ではありません。 –