Você está no caminho certo, mas há algumas coisas a serem observadas aqui, além da parte de que matrizes aninhadas (e especialmente com chaves anônimas) não são exatamente uma ótima maneira de armazenar coisas, mas contanto que você saiba consistentemente a posição que deve ser razoavelmente bem.
Há uma diferença distinta entre a correspondência de documentos e combinando "elementos de uma matriz" . Embora seu valor atual realmente não corresponda (seu valor de pesquisa não está dentro dos limites do documento), se o valor realmente for válido, sua consulta corresponde corretamente ao "documento" here, que contém um elemento correspondente na matriz.
O "documento" contém todos dos elementos da matriz, mesmo aqueles que não correspondem, mas a condição diz que o "documento" corresponde, por isso é retornado. Se você quiser apenas os "elementos" correspondentes então use
.aggregate()
em vez de: 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" }
}}
])
E isso retorna apenas os elementos que corresponderam à condição:
{
"_id" : ObjectId("536c1145e99dc11e65ed07ce"),
"info" : [
[
1399583285000,
20.13
],
[
1399583286000,
20.13
]
]
}
Ou, claro, se você esperava apenas um elemento para corresponder, então você pode simplesmente usar projeção com
.find()
**:db.infos.find(
{
"info":{
"$elemMatch":{
"0": {
"$gt": 1399583285000
}
}
}
},
{
"info.$": 1
}
)
Mas com um termo como
$gt
é provável que você obtenha várias ocorrências em um documento, portanto, a abordagem agregada será mais segura, considerando que o $
posicional operador só retornará o primeiro partida.