sql >> Database >  >> NoSQL >> MongoDB

Documenten vinden met exact dezelfde matrixvermeldingen als in een query

Er zijn hier verschillende "zeer nuttige gevallen" waarbij het proberen om een ​​"unieke hash" over de array-inhoud te creëren, in feite "in de weg staat" van de talloze problemen die gemakkelijk kunnen worden aangepakt.

Gemeenschappelijk vinden voor "Ik"

Als u bijvoorbeeld "gebruiker 1" uit het verstrekte voorbeeld neemt en bedenkt dat u die gegevens al hebt geladen en "die met mij gemeen" wilt vinden door de overeenkomende "itemsIds" van wat het huidige gebruikersobject heeft, dan is er zijn twee eenvoudige zoekmethoden:

  1. Vind "precies" hetzelfde: Is waar u andere gebruikersgegevens wilt inspecteren om die gebruikers te zien die dezelfde "exacte" interesses hebben. Dit is een eenvoudig en "ongeordend" gebruik van de $alles query-operator:

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

    Die "gebruiker 3" zal retourneren, omdat zij degene zijn met "beide" gemeenschappelijke "itemsIds" -items. Volgorde is hier niet belangrijk, het is altijd een match in een willekeurige volgorde, zolang ze er maar zijn. Dit is een andere vorm van $and als query-argumenten.

  2. Vind "vergelijkbaar" met mij": Dat is in feite vragen "heb je iets dat hetzelfde is?" . Daarvoor kun je de $in query-operator. Het komt overeen als aan "een van de" voorwaarden is voldaan:

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

    In dit geval zullen "beide" de "gebruiker 2" en "gebruiker 3" overeenkomen, aangezien ze "minstens" "één" van de gespecificeerde voorwaarden delen en dat betekent dat ze "iets gemeen" hebben met de brongegevens van de vraag.

    Dit is in feite een andere vorm van de $of query-operator, en net als voorheen is het een stuk eenvoudiger en beknopter om op deze manier te schrijven gezien de te hanteren voorwaarden.

Veelvoorkomende "dingen" vinden

Er zijn ook gevallen waarin u dingen "gemeenschappelijk" wilt vinden zonder een basis "gebruiker" te hebben om mee te beginnen. Dus hoe weet je dat "gebruiker 1" en "gebruiker 2" dezelfde "itemIds" delen, of in feite dat verschillende gebruikers dezelfde "itemIds"-waarde individueel kunnen delen, maar wie zijn ze?

  1. Verkrijg de exacte overeenkomsten: Is natuurlijk waar je kijkt naar de "itemsIds" waarden en $group Hun samen. Over het algemeen is de "bestelling" hier belangrijk, dus optimaal heb je ze "vooraf besteld" en consequent altijd om dit zo eenvoudig te maken als:

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

    En dat is alles, zolang de bestelling er maar is. Als dat niet het geval is, kunt u een iets langer formulier gebruiken om de "bestelling" uit te voeren, maar hetzelfde kan worden gezegd van het genereren van een "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" }
        }}
    ])
    

    Niet "super" performant, maar het maakt duidelijk waarom je altijd geordend blijft bij het toevoegen van array-items. Dat is een heel eenvoudig proces.

  2. Gemeenschappelijke "gebruiker" tot "items": Dat is een ander eenvoudig proces dat hierboven abstraheert met het "afbreken" van de array onder $unwind , en dan in feite terug groeperen:

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

    En nogmaals, gewoon een eenvoudige groeperingsaggregator van $ addToSet doet het werk en verzamelt de "verschillende userId"-waarden voor elke "itemsIds" -waarde.

Dit zijn allemaal basisoplossingen, en ik zou kunnen doorgaan met "ingestelde kruispunten" en wat niet, maar dit is de "primer".

Probeer geen "hash" te berekenen, MongoDB heeft sowieso een goed "arsenaal" om de vermeldingen te matchen. Gebruik het en "misbruik het" ook, totdat het breekt. Probeer dan harder.




  1. Hoe gepagineerde / gesegmenteerde gegevens van subdocumentarray in mongo-verzameling krijgen?

  2. mongorestore willekeurige crash (fatale fout)

  3. Verwijder dubbele documenten op basis van veld

  4. Hoe push je naar een MongoDB-array met AngularJS?