Cara optimal di MongoDB versi 3.4.
Versi mongod
menyediakan $split
operator yang tentu saja membagi string seperti yang ditunjukkan di sini
.
Kami kemudian menetapkan nilai yang baru dihitung ke variabel menggunakan $let
operator variabel. Nilai baru kemudian dapat digunakan di di ekspresi untuk mengembalikan nilai "nama" dan "usia" menggunakan $arrayElemAt
operator untuk mengembalikan elemen pada indeks tertentu; 0
untuk elemen pertama dan -1
untuk elemen terakhir.
Perhatikan bahwa di di ekspresi kita perlu membagi elemen terakhir untuk mengembalikan string integer.
Akhirnya kita perlu mengulangi Cursor
objek dan berikan konversi string bilangan bulat ke numerik menggunakan Number
atau parseInt
dan gunakan operasi massal dan bulkWrite()
metode ke $set
nilai untuk bidang tersebut untuk efisiensi maksimum.
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 atau yang lebih baru.
MongoDB 3.2 tidak lagi menggunakan Bulk()
yang lama
API dan metode
yang terkait dan menyediakan bulkWrite()
metode tetapi tidak memberikan $split
jadi satu-satunya pilihan yang kami miliki di sini adalah menggunakan mapReduce()
metode untuk mengubah data kami kemudian memperbarui koleksi menggunakan operasi massal.
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 versi 2.6 atau 3.0.
Kita perlu menggunakan Bulk API yang sekarang sudah tidak digunakan lagi .
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();
}