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

MongoDB:Find dokumentgivne feltværdier i et objekt med en ukendt nøgle

Selvom du ser ud til at have nærmet dig denne struktur på grund af et problem med opdateringer ved brug af indlejrede arrays, har du virkelig kun forårsaget et andet problem ved at gøre noget andet, som ikke rigtig understøttes, og det er, at der ikke er noget "wildcard" koncept til at søge efter uspecificerede nøgler ved hjælp af standardforespørgselsoperatorerne, der er optimale.

Den eneste måde, du virkelig kan søge efter sådanne data på, er ved at bruge JavaScript-kode på serveren til at krydse nøglerne ved hjælp af $where . Dette er tydeligvis ikke en rigtig god idé, da det kræver brute force evaluering frem for at bruge nyttige ting som et indeks, men det kan gribes an på følgende måde:

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

Selvom dette vil returnere de objekter fra samlingen, der indeholder den påkrævede indlejrede værdi, skal den inspicere hvert objekt i samlingen for at udføre evalueringen. Dette er grunden til, at en sådan evaluering egentlig kun bør bruges, når den er parret med noget, der direkte kan bruge et indeks i stedet for som en hård værdi fra objektet i samlingen.

Den bedre løsning er stadig at overveje at ombygge dataene for at drage fordel af indekser i søgning. Hvor det er nødvendigt at opdatere "vurderings"-oplysningerne, så "flad" strukturen til at betragte hvert "rating"-element som de eneste matrixdata i stedet:

{
    "_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 er søgningen selvfølgelig ret enkel:

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

Og selvfølgelig den positionelle $ operator kan nu bruges med den fladere struktur:

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

Dette betyder naturligvis duplikering af de "relaterede" data for hver "vurderings"-værdi, men dette er generelt omkostningerne ved at opdatere efter matchet position, da det er alt, der kun understøttes med et enkelt niveau af array-nesting.

Så du kan tvinge logikken til at matche den måde, du har den struktureret på, men det er ikke en god idé at gøre det og vil føre til præstationsproblemer. Men hvis dit primære behov her er at opdatere "vurderings"-oplysningerne i stedet for blot at tilføje til den indre liste, så vil en fladere struktur være til større fordel og naturligvis være meget hurtigere at søge.




  1. Ingen Json-deserializer fundet for typen Option[reactivemongo.bson.BSONObjectID]

  2. gem adgangskode som saltet hash i mongodb i brugersamling ved hjælp af python/bcrypt

  3. Mongodb windows opsætning admin webkonsol venter på forbindelser på port 28017 fejl

  4. Node.js, (Hej)Redis og multikommandoen