Cách hiệu quả nhất để làm điều này là trong bản phát hành sắp tới của MongoDB kể từ khi viết bài này bằng cách sử dụng $split
toán tử để tách chuỗi của chúng tôi thành hiển thị ở đây
sau đó chỉ định phần tử cuối cùng trong mảng cho một biến bằng cách sử dụng $let
toán tử biến và $arrayElemAt
các toán tử.
Tiếp theo, chúng tôi sử dụng $switch
toán tử để thực hiện xử lý điều kiện logic hoặc câu lệnh trường hợp đối với biến đó.
Điều kiện ở đây là $gt
trả về true nếu giá trị chứa "test"
và trong trường hợp nào trong in biểu thức chúng tôi tách chuỗi đó và chỉ cần trả về $concat
giá trị riêng của phần tử đầu tiên trong mảng mới được tính và -
. Nếu điều kiện cho giá trị là false, chúng tôi chỉ trả về biến.
Tất nhiên trong câu lệnh trường hợp của chúng tôi, chúng tôi sử dụng $indexOfCP
trả về -1
nếu không có sự xuất hiện của "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"
}
}
}
}
}}
]
)
Truy vấn tổng hợp tạo ra một cái gì đó giống như sau:
{ "_id" : ObjectId("57a98773cbbd42a2156260d8"), "data" : 11, "version" : "32" }
{ "_id" : ObjectId("57a98773cbbd42a2156260d9"), "data" : 55, "version" : "-42" }
Như bạn có thể thấy, dữ liệu trường "phiên bản" là chuỗi. Nếu loại dữ liệu cho trường đó không quan trọng thì bạn chỉ cần sử dụng $out
nhà điều hành giai đoạn đường ống tổng hợp để ghi kết quả vào một tập hợp mới hoặc thay thế tập hợp của bạn.
{ "out": "collection" }
Nếu bạn cần chuyển đổi dữ liệu của mình thành số dấu phẩy động thì cách duy nhất để thực hiện việc này, đơn giản vì MongoDB không cung cấp cách thực hiện chuyển đổi kiểu ngoại trừ số nguyên thành chuỗi, là lặp lại con trỏ tổng hợp. đối tượng và chuyển đổi giá trị của bạn bằng cách sử dụng parseFloat
hoặc Number
sau đó cập nhật tài liệu của bạn bằng $set
toán tử và bulkWrite()
phương pháp để đạt hiệu quả tối đa.
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);
}
Mặc dù truy vấn tổng hợp sẽ hoạt động hoàn hảo trong MongoDB 3.4 hoặc mới hơn, đặt cược tốt nhất của chúng tôi từ MongoDB 3.2 trở về trước là mapReduce
với bulkWrite()
phương pháp.
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
trông như thế này:
[
{
"_id" : ObjectId("57a98773cbbd42a2156260d8"),
"value" : "32"
},
{
"_id" : ObjectId("57a98773cbbd42a2156260d9"),
"value" : "-42"
}
]
Từ đây, bạn sử dụng .forEach
vòng lặp để cập nhật tài liệu của bạn.
Từ MongoDB 2.6 đến 3.0, bạn sẽ cần sử dụng Bulk()
API và phương thức được liên kết với nó như được hiển thị trong câu trả lời của tôi tại đây.