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

So finden Sie Dokumente mit genau denselben Array-Einträgen wie in einer Abfrage

Hier gibt es mehrere "sehr nützliche Fälle", in denen der Versuch, einen "eindeutigen Hash" über den Array-Inhalt zu erstellen, tatsächlich den unzähligen Problemen "im Weg steht", die leicht angegangen werden können.

Mit "mir" gemeinsam finden

Wenn Sie beispielsweise "Benutzer 1" aus dem bereitgestellten Beispiel nehmen und bedenken, dass Sie diese Daten bereits geladen haben und "die mit mir gemeinsamen" anhand der übereinstimmenden "itemsIds" aus dem aktuellen Benutzerobjekt finden möchten, dann dort sind zwei einfache Abfrageansätze:

  1. Finde "genau" dasselbe: Hier möchten Sie andere Benutzerdaten überprüfen, um diejenigen Benutzer zu sehen, die die gleichen "genauen" Interessen haben. Dies ist eine einfache und „ungeordnete“ Verwendung des $all Abfrageoperator:

    db.collection.find({ 
        "itemsIds": { "$all": [399957190, 366369952] },
        "userId": { "$ne": 1 }
    })
    

    Was "Benutzer 3" zurückgeben wird, da sie derjenige mit "beiden" gemeinsamen "itemsIds" -Einträgen sind. Die Reihenfolge ist hier nicht wichtig, da es immer eine Übereinstimmung in jeder Reihenfolge gibt, solange beide vorhanden sind. Dies ist eine andere Form von $and als Abfrageargumente.

  2. Finde "ähnlich" mit mir gemeinsam: Das ist im Grunde die Frage "Haben Sie etwas, das gleich ist?" . Dafür können Sie den $in Abfrageoperator. Es wird übereinstimmen, wenn „eine“ der angegebenen Bedingungen erfüllt ist:

    db.collection.find({ 
        "itemsIds": { "$in": [399957190, 366369952] },
        "userId": { "$ne": 1 }
    })
    

    In diesem Fall stimmen "beide" "Benutzer 2" und "Benutzer 3" überein, da sie "mindestens" "eine" der angegebenen Bedingungen gemeinsam haben und das bedeutet, dass sie "etwas gemeinsam" mit den Quelldaten von haben die Abfrage.

    Dies ist tatsächlich eine andere Form von $or Abfrageoperator, und genau wie zuvor ist es angesichts der anzuwendenden Bedingungen viel einfacher und prägnanter, auf diese Weise zu schreiben.

Gemeinsame "Dinge" finden

Es gibt auch Fälle, in denen Sie Dinge finden möchten, die "gemeinsam" sind, ohne einen Basis-"Benutzer" zu haben, von dem aus Sie beginnen können. Wie sagen Sie also, dass "Benutzer 1" und "Benutzer 2" dieselben "itemIds" teilen, oder dass verschiedene Benutzer tatsächlich denselben "itemIds"-Wert haben, aber wer sind sie?

  1. Holen Sie sich die genauen Übereinstimmungen: Hier sehen Sie sich natürlich die "itemsIds"-Werte und an $group Sie zusammen. Generell ist hier die "Bestellung wichtig", also am besten Sie haben sie "vorbestellt" und das konsequent immer so einfach wie:

    db.collection.aggregate([
        { "$group": {
            "_id": "$itemsIds",
            "common": { "$push": "$userId" }
        }}
    ])
    

    Und das ist auch schon alles, solange die Bestellung schon da ist. Wenn nicht, dann können Sie ein etwas längeres Formular verwenden, um die "Bestellung" durchzuführen, aber das Gleiche könnte gesagt werden, um einen "Hash" zu erzeugen:

    db.collection.aggregate([
        { "$unwind": "$itemsIds" },
        { "$sort": { "_id": 1, "itemsIds": 1 } },
        { "$group": {
            "_id": "$_id",
            "userId": { "$first": "$userId" },
            "itemsIds": { "$push": "$itemsIds" }
        }},
        { "$group": {
            "_id": "$itemsIds",
            "common": { "$push": "$userId" }
        }}
    ])
    

    Nicht "super" leistungsfähig, aber es macht den Punkt, warum Sie beim Hinzufügen von Array-Einträgen immer geordnet bleiben. Das ist ein sehr einfacher Vorgang.

  2. Gemeinsamer "Benutzer" für "Elemente": Dies ist ein weiterer einfacher Prozess, der oben mit dem "Aufteilen" des Arrays unter $unwind abstrahiert , und dann im Grunde wieder gruppieren:

    db.collection.aggregate([
        { "$unwind": "$itemsIds" },
        { "$group": {
            "_id": "$itemsIds",
            "users": { "$addToSet": "$userId" }
        }}
    ])
    

    Und wieder nur ein einfacher Gruppierungsaggregator von $ addToSet erledigt die Aufgabe und sammelt die "distinct userId"-Werte für jeden "itemsIds"-Wert.

Dies sind alles grundlegende Lösungen, und ich könnte mit "Schnittpunkten setzen" und so weitermachen, aber dies ist die "Grundierung".

Versuchen Sie nicht, einen "Hash" zu berechnen, MongoDB hat sowieso ein gutes "Arsenal", um die Einträge abzugleichen. Benutze es und "missbrauche es" auch, bis es kaputt geht. Dann streng dich an.