sql >> Databasteknik >  >> NoSQL >> MongoDB

Det effektivaste sättet att ändra ett strängfältvärde till dess understräng

Det mest effektiva sättet att göra detta är i den kommande versionen av MongoDB när detta skrivs med hjälp av $split operatör för att dela upp vår sträng som visas här tilldela sedan det sista elementet i arrayen till en variabel med $let variabeloperatorn och $arrayElemAt operatörer.

Därefter använder vi $switch operatör för att utföra en logisk tillståndsbearbetning eller fallutlåtande mot den variabeln.

Villkoret här är $gt som returnerar sant om värdet innehåller "test" , och i så fall i in uttryck vi delar upp den strängen och returnerar helt enkelt $concat enat värde för det första elementet i den nyligen beräknade arrayen och - . Om villkoret utvärderas till falskt returnerar vi bara variabeln.

Naturligtvis använder vi $indexOfCP i vår case statement som returnerar -1 om det inte fanns några förekomster av "test" .

let cursor = db.collection.aggregate(
    [
        { "$project": { 
            "data": 1, 
            "version": { 
                "$let": { 
                    "vars": { 
                        "v": { 
                            "$arrayElemAt": [
                                { "$split": [ "$version", "." ] }, 
                                -1
                            ]
                        }
                    }, 
                    "in": { 
                        "$switch": { 
                            "branches": [ 
                                { 
                                    "case": { 
                                        "$gt": [ 
                                            { "$indexOfCP": [ "$$v", "test" ] },
                                            -1 
                                        ]
                                    }, 
                                    "then": { 
                                        "$concat": [ 
                                            "-", 
                                            "", 
                                            { "$arrayElemAt": [
                                                { "$split": [ "$$v", "-" ] }, 
                                                0 
                                            ]} 
                                        ]
                                    }
                                }
                            ], 
                            "default": "$$v" 
                        }
                    }
                }
            }
        }}
    ]
)

Aggregeringsfrågan ger något i stil med detta:

{ "_id" : ObjectId("57a98773cbbd42a2156260d8"), "data" : 11, "version" : "32" }
{ "_id" : ObjectId("57a98773cbbd42a2156260d9"), "data" : 55, "version" : "-42" }

Som du kan se är "version"-fältdata strängar. Om datatypen för det fältet inte spelar någon roll kan du helt enkelt använda $out aggregation pipeline stage operator för att skriva resultatet till en ny samling eller ersätta din samling.

{ "out": "collection" }

Om du behöver konvertera dina data till flyttal, är det enda sättet att göra detta, helt enkelt för att MongoDB inte tillhandahåller ett sätt att göra typkonvertering ur lådan förutom heltal till sträng, att iterera aggregeringsmarkören objekt och konvertera ditt värde med parseFloat eller Number uppdatera sedan dina dokument med $set operatorn och bulkWrite() metod för maximal effektivitet.

let requests = [];
cursor.forEach(doc => { 
    requests.push({ 
        "updateOne": { 
            "filter": { "_id": doc._id }, 
            "update": { 
                "$set": { 
                    "data": doc.data, 
                    "version": parseFloat(doc.version) 
                },
                "$unset": { "person": " " }
            } 
        } 
    }); 
    if ( requests.length === 1000 ) { 
        // Execute per 1000 ops and re-init
        db.collection.bulkWrite(requests); 
        requests = []; 
    }} 
);

 // Clean up queues
if(requests.length > 0) {
    db.coll.bulkWrite(requests);
}

Medan aggregeringsfrågan kommer att fungera perfekt i MongoDB 3.4 eller senare är vår bästa insats från MongoDB 3.2 bakåt mapReduce med bulkWrite() metod.

var results = db.collection.mapReduce(
    function() { 
        var v = this.version.split(".")[2]; 
        emit(this._id, v.indexOf("-") > -1 ? "-"+v.replace(/\D+/g, '') : v)
    }, 
    function(key, value) {}, 
    { "out": { "inline": 1 } }
)["results"];

results ser ut så här:

[
    {
        "_id" : ObjectId("57a98773cbbd42a2156260d8"),
        "value" : "32"
    },
    {
        "_id" : ObjectId("57a98773cbbd42a2156260d9"),
        "value" : "-42"
    }
]

Härifrån använder du den tidigare .forEach loop för att uppdatera dina dokument.

Från MongoDB 2.6 till 3.0 måste du använda den nu utfasade Bulk() API och den associerade metoden som visas i mitt svar här.




  1. Varför trycker inte Spark Mongo-kontakten ned filtren?

  2. Få en lista över alla unika taggar i mongodb

  3. docker-compose + django + redis - Fel 111 vid anslutning till 127.0.0.1:6379. Anslutningen vägrades

  4. Mongoid:använder du mer än en databas?