Jesteś na dobrej drodze, ale jest tu kilka rzeczy do zapamiętania, poza częścią, że zagnieżdżone tablice (a zwłaszcza z kluczami anonimowymi) nie są do końca świetnym sposobem na przechowywanie rzeczy, ale tak długo, jak konsekwentnie znasz pozycję, wtedy to powinno być w porządku.
Istnieje wyraźna różnica między pasującymi dokumentami i pasujące „elementy tablicy” . Chociaż bieżąca wartość w rzeczywistości nie byłaby zgodna (wartość wyszukiwania nie mieści się w granicach dokumentu), jeśli wartość rzeczywiście była prawidłowa, zapytanie poprawnie pasuje do „dokumentu” tutaj, który zawiera pasujący element w tablicy.
„dokument” zawiera wszystkie elementów tablicy, nawet tych, które nie pasują, ale warunek mówi "dokument" pasuje, więc jest zwracany. Jeśli chcesz tylko pasujących „elementów” następnie użyj .aggregate()
zamiast tego:
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" }
}}
])
A to zwraca tylko te elementy, które pasują do warunku:
{
"_id" : ObjectId("536c1145e99dc11e65ed07ce"),
"info" : [
[
1399583285000,
20.13
],
[
1399583286000,
20.13
]
]
}
Lub oczywiście, jeśli spodziewałeś się tylko jednego element do dopasowania, możesz po prostu użyć rzutowania z .find()
**:
db.infos.find(
{
"info":{
"$elemMatch":{
"0": {
"$gt": 1399583285000
}
}
}
},
{
"info.$": 1
}
)
Ale z terminem takim jak $gt
prawdopodobnie otrzymasz wiele trafień w dokumencie, więc podejście agregujące będzie bezpieczniejsze, biorąc pod uwagę, że pozycyjny $
operator zwróci tylko pierwszy dopasuj.