sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur man hittar dokument med exakt samma arrayposter som i en fråga

Det finns flera "mycket användbara fall" här där ett försök att skapa en "unik hash" över arrayinnehållet faktiskt "kommer i vägen" för den myriad av problem som lätt kan lösas.

Hitta gemensamt för "Mig"

Om du till exempel tar "användare 1" från exemplet som tillhandahålls och anser att du redan har den datan laddad och vill hitta "de som är gemensamma med mig" av de matchade "itemsIds" från vad det aktuella användarobjektet har, så finns det är två enkla frågemetoder:

  1. Hitta "exakt" samma: Det är där du vill inspektera andra användardata för att se de användare som har samma "exakta" intressen. Detta är enkel och "oordnad" användning av $all frågeoperator:

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

    Vilket kommer att returnera "användare 3" eftersom de är den med "båda" vanliga "itemsIds"-poster. Ordning är inte viktigt här då det alltid är en match i vilken ordning som helst, så länge de båda är där. Detta är en annan form av $and som frågeargument.

  2. Hitta "liknande" gemensamt för mig": Vilket i princip är att fråga "har du något som är lika?" . För det kan du använda $in frågeoperatör. Det kommer att matcha om "endera" av de angivna villkoren är uppfyllda:

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

    I det här fallet kommer "både" "användare 2" och "användare 3" att matcha, eftersom de "minst" delar "ett" av de angivna villkoren och det betyder att de har "något gemensamt" med källdata för frågan.

    Detta är faktiskt en annan form av $or frågeoperator, och precis som tidigare är det mycket enklare och kortfattat att skriva på det här sättet givet de villkor som ska tillämpas.

Hitta vanliga "saker"

Det finns också fall där du kanske vill hitta saker "gemensamt" utan att ha en bas "användare" att utgå ifrån. Så hur vet man att "användare 1" och "användare 2" delar samma "varu-ID", eller att flera av användarna kanske delar samma "varu-ID"-värde individuellt, men vilka är de?

  1. Få exakta matchningar: Är naturligtvis där du tittar på "itemsIds"-värdena och $grupp dem tillsammans. I allmänhet är "ordningen viktig" här, så optimalt sett har du dem "förbeställda" och konsekvent alltid för att göra detta så enkelt som:

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

    Och det är allt som finns egentligen, så länge ordern redan finns där. Om inte, så kan du göra en lite längre vindad form för att göra "beställningen", men detsamma kan sägas om att generera en "hash":

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

    Inte "super" presterande, men det gör poängen till varför du alltid håller ordning på tillägg av arrayposter. Vilket är en mycket enkel process.

  2. Vanlig "användare" till "objekt": Vilket är en annan enkel process som abstraherar ovan med att "bryta ner" arrayen under $unwind , och sedan i princip gruppera tillbaka:

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

    Och återigen, bara en enkel grupperingsaggregator av $ addToSet gör jobbet och samlar in "distinct userId"-värdena för varje "itemIds"-värde.

Dessa är alla grundläggande lösningar, och jag skulle kunna fortsätta med "ställ in korsningar" och vad inte, men det här är "primern".

Försök inte beräkna en "hash", MongoDB har en bra "arsenal" för att matcha posterna ändå. Använd den och "missbruka den" också, tills den går sönder. Försök sedan hårdare.




  1. Stöder Spring Data MongoDB MongoDB 3.4 sorteringsfunktion?

  2. Vad är bästa praxis för MongoDB-anslutningar på Node.js?

  3. Redis hash mycket långsam skrivhastighet

  4. Automatisk ökningssekvens i NestJs/Mongoose