Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Ép kiểu (Cast) trong truy vấn MongoDB

MongoDB shell cho phép dùng JavaScript expression trong find() để thực hiện ép kiểu (cast) ngầm định khi so sánh.

Cú pháp

db.collection.find("this.trường > giáTrị");

Trong chuỗi query, this tham chiếu đến document hiện tại. JavaScript sẽ tự chuyển đổi kiểu khi so sánh.

Ví dụ minh họa

Tạo collection castingDemo với field Amount lưu dưới dạng **String**:

> db.castingDemo.insertOne({ "Amount": "200" });
> db.castingDemo.insertOne({ "Amount": "100" });
> db.castingDemo.insertOne({ "Amount": "110" });
> db.castingDemo.insertOne({ "Amount": "95" });
> db.castingDemo.insertOne({ "Amount": "85" });
> db.castingDemo.insertOne({ "Amount": "75" });

Hiển thị:

> db.castingDemo.find().pretty();

Kết quả:

{ "_id" : ..., "Amount" : "200" }
{ "_id" : ..., "Amount" : "100" }
{ "_id" : ..., "Amount" : "110" }
{ "_id" : ..., "Amount" : "95" }
{ "_id" : ..., "Amount" : "85" }
{ "_id" : ..., "Amount" : "75" }

Truy vấn: Amount > 85 (tự ép string sang number)

> db.castingDemo.find("this.Amount > 85");

Kết quả: Các document có Amount = "200", "100", "110", "95".

{ "_id" : ..., "Amount" : "200" }
{ "_id" : ..., "Amount" : "100" }
{ "_id" : ..., "Amount" : "110" }
{ "_id" : ..., "Amount" : "95" }

Cách hiện đại & khuyên dùng: $expr (Aggregation trong find)

Từ MongoDB 3.6, dùng $expr với các toán tử aggregation ($gt, $toInt, $toDouble...) rõ ràng và an toàn hơn:

// Ép kiểu tường minh với $toInt
db.castingDemo.find({ $expr: { $gt: [ { $toInt: "$Amount" }, 85 ] } });

// Hoặc $convert (MongoDB 4.0+) với xử lý lỗi
db.castingDemo.find({ $expr: { $gt: [ { $convert: { input: "$Amount", to: "int", onError: 0 } }, 85 ] } });

So sánh 2 cách

Đặc điểmfind("this...")find({ $expr: ... })
Cú phápJavaScript stringAggregation expression (object)
Ép kiểuNgầm định (JS type coercion)Tường minh ($toInt, $toDouble...)
Sử dụng Index**Không thể** dùng index**Không thể** dùng index (cần $expr)
An toànRủi ro injection, lỗi type lạAn toàn, chuẩn MongoDB
Hỗ trợLegacy shellMongoDB 3.6+ (khuyên dùng)

Lưu ý

  • Cả 2 cách **không sử dụng index** trên field Amount vì phải tính toán trên mỗi document.
  • Giải pháp tối ưu: **Chuẩn hóa dữ liệu** (store as Number) hoặc dùng **Schema Validation** ép kiểu khi insert.
  • Trong driver (Node.js, Python...): Không dùng được "this...". Phải dùng $expr hoặc xử lý ở application layer.