sql >> Database >  >> NoSQL >> MongoDB

MongoDB:Zoek document gegeven veldwaarden in een object met een onbekende sleutel

Hoewel je deze structuur lijkt te hebben benaderd vanwege een probleem met updates bij het gebruik van geneste arrays, heb je echt alleen maar een ander probleem veroorzaakt door iets anders te doen dat niet echt wordt ondersteund, en dat is dat er geen "wildcard" concept voor het zoeken naar niet-gespecificeerde sleutels met behulp van de standaard query-operators die optimaal zijn.

De enige manier waarop u echt naar dergelijke gegevens kunt zoeken, is door JavaScript-code op de server te gebruiken om de sleutels te doorkruisen met behulp van $where . Dit is duidelijk niet echt een goed idee omdat het brute kracht vereist evaluatie in plaats van het gebruik van nuttige dingen zoals een index, maar het kan als volgt worden benaderd:

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

Hoewel dit de objecten uit de verzameling retourneert die de vereiste geneste waarde bevatten, moet het elk object in de verzameling inspecteren om de evaluatie uit te voeren. Dit is de reden waarom een ​​dergelijke evaluatie eigenlijk alleen zou moeten worden gebruikt in combinatie met iets dat in plaats daarvan rechtstreeks een index kan gebruiken als een harde waarde van het object in de verzameling.

Nog steeds is de betere oplossing om te overwegen de gegevens opnieuw te modelleren om te profiteren van indexen bij het zoeken. Waar het nodig is om de "beoordelingen"-informatie bij te werken, dan in feite "afvlakken" de structuur om in plaats daarvan elk "rating"-element als de enige arraygegevens te beschouwen:

{
    "_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
        }
   ]
}

Nu is zoeken natuurlijk vrij eenvoudig:

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

En natuurlijk de positionele $ operator kan nu worden gebruikt met de plattere structuur:

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

Dit betekent natuurlijk duplicatie van de "gerelateerde" gegevens voor elke "ratings"-waarde, maar dit zijn over het algemeen de kosten om te updaten op overeenkomende positie, aangezien dit alles is dat wordt ondersteund met alleen een enkel niveau van array-nesting.

Je kunt de logica dus dwingen om overeen te komen met de manier waarop je het gestructureerd hebt, maar het is geen goed idee om dit te doen en zal leiden tot prestatieproblemen. Als uw belangrijkste behoefte hier echter is om de "beoordelingen"-informatie bij te werken in plaats van alleen toe te voegen aan de binnenste lijst, dan zal een plattere structuur van groter voordeel zijn en natuurlijk een stuk sneller zoeken.




  1. Redis Cheatsheet voor geheugenoptimalisatie

  2. MongoDB MapReduce-update op zijn plaats hoe?

  3. Aggregate framework kan geen indexen gebruiken

  4. Aan de slag met ClusterControl