MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Gestalten Sie Dokumente um, indem Sie einen Feldwert aufteilen

Der optimale Weg in MongoDB Version 3.4.

Diese Version von mongod stellt den $split bereit -Operator, der den String natürlich wie hier gezeigt aufspaltet .

Anschließend weisen wir den neu berechneten Wert mithilfe des einer Variablen zu $let Variablenoperator. Der neue Wert kann dann im in verwendet werden -Ausdruck, um die Werte „Name“ und „Alter“ mithilfe des Codes $arrayElemAt Operator, um das Element an einem bestimmten Index zurückzugeben; 0 für das erste Element und -1 für das letzte Element.

Beachten Sie, dass in in Ausdruck müssen wir das letzte Element aufteilen, um die Ganzzahl-Zeichenfolge zurückzugeben.

Schließlich müssen wir den Cursor iterieren -Objekt und wandeln Sie den Integer-String mithilfe von Nummer oder parseInt und verwenden Sie die Massenoperation und den bulkWrite() Methode zu $set der Wert für diese Felder für maximale Effizienz.

let requests = [];
db.coll.aggregate(
    [
        { "$project": {  
            "person": { 
                "$let": { 
                    "vars": { 
                        "infos":  { "$split": [ "$person", "," ] } 
                    }, 
                    "in": { 
                        "name": { "$arrayElemAt": [ "$$infos", 0 ] }, 
                        "age": { 
                            "$arrayElemAt": [ 
                                { "$split": [ 
                                    { "$arrayElemAt": [ "$$infos", -1 ] }, 
                                    " " 
                                ]}, 
                                -1 
                            ] 
                        } 
                    } 
                } 
            }  
        }}
    ] 
).forEach(document => { 
    requests.push({ 
        "updateOne": { 
            "filter": { "_id": document._id }, 
            "update": { 
                "$set": { 
                    "name": document.person.name, 
                    "age": Number(document.person.age) 
                },
                "$unset": { "person": " " }
            } 
        } 
    }); 
    if ( requests.length === 500 ) { 
        // Execute per 500 ops and re-init
        db.coll.bulkWrite(requests); 
        requests = []; 
    }} 
);

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

MongoDB 3.2 oder neuer.

MongoDB 3.2 verwirft das alte Bulk() API und die zugehörigen Methoden und stellt das bulkWrite() bereit -Methode, stellt aber nicht den $split bereit Operator, also ist die einzige Option, die wir hier haben, die Verwendung des mapReduce() Methode, um unsere Daten umzuwandeln und dann die Sammlung mithilfe eines Massenvorgangs zu aktualisieren.

var mapFunction = function() { 
    var person = {}, 
    infos = this.person.split(/[,\s]+/); 
    person["name"] = infos[0]; 
    person["age"] = infos[2]; 
    emit(this._id, person); 
};

var results = db.coll.mapReduce(
    mapFunction, 
    function(key, val) {}, 
    { "out": { "inline": 1 } }
)["results"];

results.forEach(document => { 
    requests.push({ 
        "updateOne": { 
            "filter": { "_id": document._id }, 
            "update": { 
                "$set": { 
                    "name": document.value.name, 
                    "age": Number(document.value.age) 
                }, 
                "$unset": { "person": " " }
            } 
        } 
    }); 
    if ( requests.length === 500 ) { 
        // Execute per 500 operations and re-init
        db.coll.bulkWrite(requests); 
        requests = []; 
    }} 
);

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

MongoDB-Version 2.6 oder 3.0.

Wir müssen die jetzt veraltete Bulk-API verwenden .

var bulkOp = db.coll.initializeUnorderedBulkOp();
var count = 0;

results.forEach(function(document) { 
    bulkOp.find({ "_id": document._id}).updateOne(
        { 
            "$set": { 
                "name": document.value.name, 
                "age": Number(document.value.age)
            },
            "$unset": { "person": " " }
        }
    );
    count++;
    if (count === 500 ) {
        // Execute per 500 operations and re-init
        bulkOp.execute();
        bulkOp = db.coll.initializeUnorderedBulkOp();
    }
});

// clean up queues
if (count > 0 ) {
    bulkOp.execute();
}