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

MongoDB:Finden Sie dokumentangegebene Feldwerte in einem Objekt mit einem unbekannten Schlüssel

Obwohl Sie sich dieser Struktur anscheinend aufgrund eines Problems mit Aktualisierungen bei der Verwendung verschachtelter Arrays genähert haben, haben Sie wirklich nur ein anderes Problem verursacht, indem Sie etwas anderes getan haben, das nicht wirklich unterstützt wird, und das ist, dass es keinen "Wildcard" Konzept für die Suche nach nicht spezifizierten Schlüsseln mit den Standard-Abfrageoperatoren, die optimal sind.

Die einzige Möglichkeit, wirklich nach solchen Daten zu suchen, besteht darin, JavaScript-Code auf dem Server zu verwenden, um die Schlüssel mit $where . Dies ist eindeutig keine wirklich gute Idee, da es rohe Gewalt erfordert Bewertung, anstatt nützliche Dinge wie einen Index zu verwenden, aber es kann wie folgt angegangen werden:

db.theses.find(function() {
    var relations = this.relations;
    return Object.keys(relations).some(function(rel) {
        return relations[rel].type == "interpretation";
    });
))

Während dies die Objekte aus der Sammlung zurückgibt, die den erforderlichen verschachtelten Wert enthalten, muss es jedes Objekt in der Sammlung untersuchen, um die Auswertung durchzuführen. Aus diesem Grund sollte eine solche Auswertung wirklich nur verwendet werden, wenn sie mit etwas gepaart ist, das einen Index direkt verwenden kann, anstatt einen harten Wert aus dem Objekt in der Sammlung.

Dennoch ist es die bessere Lösung, die Daten neu zu modellieren, um Indizes bei der Suche zu nutzen. Wo es notwendig ist, die "Ratings"-Informationen zu aktualisieren, dann im Grunde "flatten" die Struktur, um stattdessen jedes "Rating"-Element als die einzigen Array-Daten zu betrachten:

{
    "_id": "aeokejXMwGKvWzF5L",
    "text": "test",
    "relationsRatings": [
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 1,
            "ratingScore": 5
        },
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 2,
            "ratingScore": 6
        }
   ]
}

Jetzt ist die Suche natürlich ganz einfach:

db.theses.find({ "relationsRatings.type": "interpretation" })

Und natürlich der Positions-$ Operator kann jetzt mit der flacheren Struktur verwendet werden:

db.theses.update(
    { "relationsRatings.ratingId": 1 },
    { "$set": { "relationsRatings.$.ratingScore": 7 } }
)

Dies bedeutet natürlich eine Duplizierung der „zugehörigen“ Daten für jeden „Ratings“-Wert, aber dies ist im Allgemeinen der Preis für die Aktualisierung nach übereinstimmender Position, da dies alles ist, was nur mit einer einzigen Ebene der Array-Verschachtelung unterstützt wird.

Sie können also zwingen, dass die Logik mit der Art und Weise übereinstimmt, wie Sie sie strukturiert haben, aber das ist keine gute Idee und führt zu Leistungsproblemen. Wenn Sie hier jedoch hauptsächlich die "Bewertungen"-Informationen aktualisieren und nicht nur an die innere Liste anhängen möchten, ist eine flachere Struktur von größerem Vorteil und natürlich viel schneller zu durchsuchen.