Theo mặc định, tất cả các "số" được lưu trữ dưới dạng "kép" trong MongoDB trừ khi thường được truyền ngược chiều.
Lấy các mẫu sau:
db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })
Điều này tạo ra một bộ sưu tập như thế này:
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
Mặc dù các hàm khởi tạo khác nhau, hãy lưu ý rằng một số điểm dữ liệu ở đó trông giống nhau như thế nào. Bản thân vỏ MongoDB không phải lúc nào cũng phân biệt rạch ròi giữa chúng, nhưng có một cách bạn có thể biết được.
Tất nhiên là có $type
toán tử truy vấn, cho phép lựa chọn Loại BSON.
Vì vậy, hãy kiểm tra điều này với Loại 1 - Loại "kép":
> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
Bạn thấy rằng cả phần chèn đầu tiên và phần cuối cùng đều được chọn, nhưng tất nhiên không phải là hai phần còn lại.
Vì vậy, bây giờ hãy kiểm tra BSON Loại 16 - là một số nguyên 32 bit
> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
Đó là lần chèn "thứ ba" sử dụng NumberInt()
chức năng trong shell. Vì vậy, chức năng đó và quá trình tuần tự hóa khác từ trình điều khiển của bạn có thể đặt loại BSON cụ thể này.
Và đối với BSON Loại 18 - là số nguyên 64 bit
> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
Chèn "thứ hai" được cấu trúc qua NumberLong()
.
Nếu bạn muốn "loại bỏ" những thứ "không phải là hai" thì bạn sẽ làm:
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})
Đó là các kiểu số hợp lệ duy nhất khác với chính "double".
Vì vậy, để "chuyển đổi" những thứ này trong bộ sưu tập của bạn, bạn có thể quy trình "Hàng loạt" như sau:
var bulk = db.sample.initializeUnorderedBulkOp(),
count = 0;
db.sample.find({
"$or": [
{ "a": { "$type": 16 } },
{ "a": { "$type": 18 } }
]
}).forEach(function(doc) {
bulk.find({ "_id": doc._id })
.updateOne({
"$set": { "b": doc.a.valueOf() } ,
"$unset": { "a": 1 }
});
bulk.find({ "_id": doc._id })
.updateOne({ "$rename": { "b": "a" } });
count++;
if ( count % 1000 == 0 ) {
bulk.execute()
bulk = db.sample.initializeUnOrderedBulkOp();
}
})
if ( count % 1000 != 0 ) bulk.execute();
Những gì thực hiện được thực hiện theo ba bước "hàng loạt":
- Truyền lại giá trị cho một trường mới dưới dạng "kép"
- Xóa trường cũ có loại không mong muốn
- Đổi tên trường mới thành tên trường cũ
Điều này cần thiết vì thông tin loại BSON "dính" với phần tử trường sau khi được tạo. Vì vậy, để "truyền lại", bạn cần phải xóa hoàn toàn dữ liệu cũ bao gồm việc gán trường ban đầu.
Vì vậy, điều đó sẽ giải thích cách "phát hiện" và cũng "truyền lại" các loại không mong muốn trong tài liệu của bạn.