MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongodb trouve dans le sous-tableau

Vous êtes sur la bonne voie, mais il y a quelques points à noter ici, à part le fait que les tableaux imbriqués (et en particulier avec des clés anonymes) ne sont pas exactement un excellent moyen de stocker des éléments, mais tant que vous connaissez toujours la position alors cela devrait être raisonnablement acceptable.

Il existe une nette différence entre les documents correspondants et correspondant à "éléments d'un tableau" . Bien que votre valeur actuelle ne corresponde pas (votre valeur de recherche n'est pas dans les limites du document), si la valeur était réellement valide, votre requête correspond correctement au "document" ici, qui contient un élément correspondant dans le tableau.

Le "document" contient tout des éléments du tableau, même ceux qui ne correspondent pas, mais la condition indique le "document" correspond, il est donc renvoyé. Si vous voulez juste les "éléments" correspondants puis utilisez .aggregate() à la place :

    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" }
        }}

    ])

Et cela renvoie uniquement les éléments qui correspondent à la condition :

{
    "_id" : ObjectId("536c1145e99dc11e65ed07ce"),
    "info" : [
            [
                    1399583285000,
                    20.13
            ],
            [
                    1399583286000,
                    20.13
            ]
    ]
}

Ou bien sûr si vous n'en attendiez qu'un élément correspondant, vous pouvez simplement utiliser la projection avec .find() ** :

db.infos.find(
    {
       "info":{
          "$elemMatch":{
             "0": {
                "$gt": 1399583285000
             }
          }
       }
    },
    {
        "info.$": 1
    }
)

Mais avec un terme comme $gt vous êtes susceptible d'obtenir plusieurs occurrences dans un document, donc l'approche agrégée sera plus sûre étant donné que le $ positionnel l'opérateur ne renverra que le premier correspondance.