Cara paling efisien untuk melakukan ini adalah dalam rilis MongoDB yang akan datang pada saat penulisan ini menggunakan $split
operator untuk membagi string kami sebagai ditampilkan di sini
lalu tetapkan elemen terakhir dalam larik ke variabel menggunakan $biarkan
operator variabel dan $arrayElemAt
operator.
Selanjutnya, kita menggunakan $switch
operator untuk melakukan pemrosesan kondisi logis atau pernyataan kasus terhadap variabel tersebut.
Syaratnya di sini adalah $gt
yang mengembalikan true jika nilainya berisi "test"
, dan dalam hal ini di ekspresi kami membagi string itu dan hanya mengembalikan $concat
nilai dari elemen pertama dalam array yang baru dihitung dan kode -
. Jika kondisi bernilai false, kami hanya mengembalikan variabel.
Tentu saja dalam pernyataan kasus kami, kami menggunakan $indexOfCP
yang mengembalikan -1
jika tidak ada kemunculan "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"
}
}
}
}
}}
]
)
Kueri agregasi menghasilkan sesuatu seperti ini:
{ "_id" : ObjectId("57a98773cbbd42a2156260d8"), "data" : 11, "version" : "32" }
{ "_id" : ObjectId("57a98773cbbd42a2156260d9"), "data" : 55, "version" : "-42" }
Seperti yang Anda lihat, data bidang "versi" adalah string. Jika tipe data untuk bidang itu tidak masalah, Anda cukup menggunakan $out
operator tahap pipa agregasi untuk menulis hasilnya ke dalam koleksi baru atau mengganti koleksi Anda.
{ "out": "collection" }
Jika Anda perlu mengonversi data Anda ke angka floating point, satu-satunya cara untuk melakukan ini, hanya karena MongoDB tidak menyediakan cara untuk melakukan konversi tipe di luar kotak kecuali integer ke string, adalah dengan mengulangi kursor agregasi objek dan konversi nilai Anda menggunakan parseFloat
atau Nomor
lalu perbarui dokumen Anda menggunakan $set
operator dan bulkWrite()
metode untuk efisiensi maksimum.
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);
}
Sementara kueri agregasi akan bekerja dengan sempurna di MongoDB 3.4 atau yang lebih baru, taruhan terbaik kami dari MongoDB 3.2 mundur adalah mapReduce
dengan bulkWrite()
metode.
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"];
hasil
terlihat seperti ini:
[
{
"_id" : ObjectId("57a98773cbbd42a2156260d8"),
"value" : "32"
},
{
"_id" : ObjectId("57a98773cbbd42a2156260d9"),
"value" : "-42"
}
]
Dari sini Anda menggunakan > .forEach loop untuk memperbarui dokumen Anda.
Dari MongoDB 2.6 hingga 3.0 Anda harus menggunakan Bulk( )
API dan metode terkaitnya seperti yang ditampilkan dalam jawaban saya di sini.