Khi sử dụng Spring Boot Starter Data MongoDB Reactive để lưu dữ liệu vào MongoDB, thư viện này sẽ mặc định chuyển đổi các giá trị BigDecimal sang String khi ghi và ngược lại khi đọc.
Điều này dẫn đến, nếu thực hiện truy vấn có so sánh giá trị liên quan đến các cột trên thì việc so sánh này sẽ được thực hiện so sánh theo kiểu String và kết quả trả về có thể sẽ không như mong đợi trong tình huống sử dụng các phép so sánh số (lớn hơn, nhỏ hơn,…)
Trên thực tế, nếu bạn sử dụng MongoDB từ version 3.4 trở đi có bổ sung thêm Decimal128, kiểu dữ liệu này tương đương với BigDecimal trong java. Vậy nên việc lưu dữ liệu theo kiểu Decimal128 sẽ giúp giải quyết được bài toán ở trên bằng cách như sau:
Trong model, đối với các field có kiểu dữ liệu BigDecimal cần chỉ định rõ kiểu dữ liệu cần chuyển đổi là Decimal128 bằng cách thêm annotation:
@Field(targetType = FieldType.DECIMAL128)
Nếu trước đó bạn đã trót lỡ lưu các số liệu BigDecimal này theo cách mặc định và dữ liệu đã bị lưu thành dạng String, đừng lo, bạn có thể chạy đoạn script sau trên MongoDB để xử lý việc convert về Decimal128:
var coll = db.getCollection('collection_name');
var bulk = coll.initializeOrderedBulkOp();
var counter = 0;
coll.find({ field_name: { $type: "string" }}).forEach(function(data) {
var updoc = {
"$set": {}
};
updoc["$set"]["field_name"] = NumberDecimal(data.field_name);
// queue the update
bulk.find({
"_id": data._id
}).update(updoc);
counter++;
if (counter % 1000 == 0) {
bulk.execute();
bulk = coll.initializeOrderedBulkOp();
}
})
if (counter % 1000 != 0) bulk.execute();
Nguyễn Văn Thắng – Java developer @ Gobiz
———-
Gobiz – Phần mềm Quản lý nhập hàng đa quốc gia
📞Hotline: 0388.432.436
📄 Fanpage: Gobiz.vn
📄 Youtube: Gobiz vn
📄 Zalo OA: Gobiz
📄 Linkedin: Gobiz Việt Nam