sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan finder du dokumenter med nøjagtig de samme array-indgange som i en forespørgsel

Der er adskillige "meget nyttige tilfælde" her, hvor det rent faktisk er at forsøge at skabe en "unik hash" over array-indholdet, faktisk "kommer i vejen" for det utal af problemer, der let kan løses.

Fælles for "Mig"

Hvis du f.eks. tager "bruger 1" fra den angivne prøve og mener, at du allerede har disse data indlæst og ønsker at finde "dem til fælles med mig" ved hjælp af de matchede "itemsIds" fra det aktuelle brugerobjekt har, så er der er to simple forespørgselstilgange:

  1. Find "præcis" det samme: Er der, hvor du vil inspicere andre brugerdata for at se de brugere, der har de samme "præcise" interesser. Dette er simpel og "uordnet" brug af $alle forespørgselsoperatør:

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

    Hvilket kommer til at returnere "bruger 3", da de er den med "begge" almindelige "itemsIds"-indgange. Orden er ikke vigtig her, da det altid er et match i enhver rækkefølge, så længe de begge er der. Dette er en anden form for $and som forespørgselsargumenter.

  2. Find "lignende" til fælles for mig": Hvilket grundlæggende er at spørge "har du noget, der er det samme?" . Til det kan du bruge $in kode> forespørgselsoperatør. Det vil matche, hvis "enhver" af de angivne betingelser er opfyldt:

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

    I dette tilfælde vil "både" "bruger 2" og "bruger 3" matche, da de "mindst" deler "en" af de angivne betingelser, og det betyder, at de har "noget til fælles" med kildedataene for forespørgslen.

    Dette er faktisk en anden form for $or forespørgselsoperator, og ligesom før er det meget enklere og kortfattet at skrive på denne måde givet de betingelser, der skal anvendes.

Find almindelige "ting"

Der er også tilfælde, hvor du måske ønsker at finde ting "fælles" uden at have en base "bruger" at tage udgangspunkt i. Så hvordan kan du se, at "bruger 1" og "bruger 2" deler de samme "itemIds", eller faktisk at flere af brugerne måske deler den samme "itemIds"-værdi individuelt, men hvem er de?

  1. Få de nøjagtige resultater: Er selvfølgelig der, du ser på "itemsIds" værdierne og $group dem sammen. Generelt er "rækkefølgen vigtig" her, så optimalt har du dem "forudbestilt" og konsekvent altid for at gøre dette så enkelt som:

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

    Og det er alt, hvad der egentlig er, så længe ordren allerede er der. Hvis ikke, så kan du lave en lidt længere vindet form for at udføre "bestillingen", men det samme kunne siges om at generere 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" }
        }}
    ])
    

    Ikke "super" performant, men det gør pointen med, hvorfor du altid holder orden på tilføjelse af array-indgange. Hvilket er en meget enkel proces.

  2. Fælles "bruger" til "varer": Hvilket er en anden simpel proces, der abstraherer på ovenfor med at "nedbryde" arrayet under $unwind , og så grundlæggende gruppering tilbage:

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

    Og igen, bare en simpel grupperingsaggregator af $ addToSet udfører opgaven og indsamler "distinct userId"-værdierne for hver "itemIds"-værdi.

Disse er alle grundlæggende løsninger, og jeg kunne fortsætte med "indstil kryds" og hvad ikke, men dette er "primeren".

Forsøg ikke at beregne en "hash", MongoDB har et godt "arsenal" til at matche posterne alligevel. Brug det og "misbrug det" også, indtil det går i stykker. Så prøv hårdere.




  1. Automatisk beregning af felter i mongodb

  2. Forespørg mongodb for betingede betingelser

  3. Gem en række (af 'tags') til MongoDB ved hjælp af Mongoose

  4. Lumen - mongodb - jenssegers/laravel-mongodb - postbud