sql >> Database >  >> NoSQL >> MongoDB

Meest efficiënte manier om een ​​tekenreeksveldwaarde te wijzigen in zijn subtekenreeks

De meest efficiënte manier om dit te doen is in de aankomende release van MongoDB vanaf dit moment van schrijven met behulp van de $split operator om onze string te splitsen als hier weergegeven wijs vervolgens het laatste element in de array toe aan een variabele met behulp van de $let variabele operator en de $arrayElemAt exploitanten.

Vervolgens gebruiken we de $switch operator om een ​​logische conditieverwerking of case-statement tegen die variabele uit te voeren.

De voorwaarde hier is $gt die true retourneert als de waarde "test" . bevat , en in dat geval in de in expressie splitsen we die string en retourneren we gewoon de $concat ingevoerde waarde van het eerste element in de nieuw berekende array en de - . Als de voorwaarde onwaar is, retourneren we de variabele.

Natuurlijk gebruiken we in onze case-statement de $indexOfCP wat -1 returns retourneert als er geen gevallen waren van "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" 
                        }
                    }
                }
            }
        }}
    ]
)

De aggregatiequery levert zoiets als dit op:

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

Zoals u kunt zien, zijn de veldgegevens "versie" een tekenreeks. Als het gegevenstype voor dat veld er dan niet toe doet, kunt u gewoon de $out . gebruiken aggregatiepijplijnfaseoperator om het resultaat naar een nieuwe verzameling te schrijven of uw verzameling te vervangen.

{ "out": "collection" }

Als u uw gegevens naar een getal met drijvende komma moet converteren, is de enige manier om dit te doen, simpelweg omdat MongoDB geen manier biedt om typeconversie uit de doos te doen, behalve integer naar string, door de aggregatiecursor te herhalen object en converteer uw waarde met parseFloat of Number werk vervolgens uw documenten bij met de $set operator en de bulkWrite() methode voor maximale efficiëntie.

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);
}

Hoewel de aggregatiequery perfect werkt in MongoDB 3.4 of nieuwer, is onze beste gok vanaf MongoDB 3.2 achteruit mapReduce met de bulkWrite() methode.

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 ziet er zo uit:

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

Vanaf hier gebruik je de vorige .forEach loop om uw documenten bij te werken.

Van MongoDB 2.6 tot 3.0 moet je de nu verouderde Bulk() API en de bijbehorende methode zoals weergegeven in mijn antwoord hier.




  1. Hoe items in een lijst met lijsten te tellen

  2. Hoe de lokale Mongo-database te verbinden met docker

  3. Speel Framework 2.5 hoe mongoDB toe te voegen?

  4. Geneste groepering met MongoDB