MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongodb findet innerhalb des Unterarrays

Sie sind auf dem richtigen Weg, aber es gibt hier ein paar Dinge zu beachten, abgesehen davon, dass verschachtelte Arrays (und insbesondere mit anonymen Schlüsseln) nicht gerade eine gute Möglichkeit sind, Dinge zu speichern, aber solange Sie die Position dann konsistent kennen das sollte halbwegs in Ordnung sein.

Es gibt einen deutlichen Unterschied zwischen übereinstimmenden Dokumenten und passende "Elemente eines Arrays" . Obwohl Ihr aktueller Wert tatsächlich nicht übereinstimmen würde (Ihr Suchwert liegt außerhalb der Grenzen des Dokuments), entspricht Ihre Abfrage korrekt dem "Dokument", wenn der Wert tatsächlich gültig war hier, die ein passendes Element im Array enthält.

Das "Dokument" enthält alle der Array-Elemente, auch diejenigen, die nicht übereinstimmen, aber die Bedingung sagt das "Dokument" stimmt überein, also wird es zurückgegeben. Wenn Sie nur die passenden "Elemente" möchten Verwenden Sie dann .aggregate() stattdessen:

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

    ])

Und das gibt nur die Elemente zurück, die der Bedingung entsprachen:

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

Oder natürlich, wenn Sie immer nur einen erwartet haben Element zu entsprechen, dann könnten Sie einfach die Projektion mit verwenden .find() **:

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

Aber mit einem Begriff wie $gt Sie werden wahrscheinlich mehrere Treffer innerhalb eines Dokuments erhalten, daher ist der aggregierte Ansatz sicherer, wenn man bedenkt, dass der positionelle $ -Operator gibt nur den ersten zurück übereinstimmen.