Вие сте на прав път, но има няколко неща, които трябва да отбележите тук, освен частта, че вложените масиви (и особено с анонимни ключове) не са точно страхотен начин за съхранение на неща, но стига да знаете постоянно позицията тогава това би трябвало да е добре.
Има ясна разлика между съвпадащите документи и съвпадащи "елементи на масив" . Въпреки че текущата ви стойност всъщност няма да съвпада (стойността ви за търсене не е в границите на документа), ако стойността действително е била валидна, вашата заявка съвпада правилно с „документа“ тук, който съдържа съответстващ елемент в масива.
„Документът“ съдържа всички от елементите на масива, дори тези, които не съвпадат, но условието казва „документ“ съвпада, така че се връща. Ако просто искате съответстващите „елементи“ след това използвайте .aggregate()
вместо това:
db.infos.aggregate([
// Still match the document
{ "$match": {
"info": {
"$elemMatch": { "0": {"$gte": 1399583285000} }
}
}},
// unwind the array for the matched documents
{ "$unwind": "$info" },
// Match only the elements
{ "$match": { "info.0": { "$gte": 1399583285000 } } },
// Group back to the original form if you want
{ "$group": {
"_id": "$_id",
"info": { "$push": "$info" }
}}
])
И това връща само елементите, които отговарят на условието:
{
"_id" : ObjectId("536c1145e99dc11e65ed07ce"),
"info" : [
[
1399583285000,
20.13
],
[
1399583286000,
20.13
]
]
}
Или разбира се, ако някога сте очаквали само едно елемент, който да съответства, тогава можете просто да използвате проекция с .find()
**:
db.infos.find(
{
"info":{
"$elemMatch":{
"0": {
"$gt": 1399583285000
}
}
}
},
{
"info.$": 1
}
)
Но с термин като $gt
е вероятно да получите множество посещения в рамките на един документ, така че обобщеният подход ще бъде по-безопасен, като се има предвид, че позиционният $
операторът ще върне само първия съвпадение.