MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Mongodb encontra dentro do sub array


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.