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

Cách so sánh giá trị các trường (field) trong MongoDB

Giới thiệu

Để so sánh giá trị giữa hai trường trong cùng một tài liệu, MongoDB cung cấp toán tử $where cho phép sử dụng biểu thức JavaScript. Tuy nhiên, cách này có hiệu suất kém hơn so với các toán tử truy vấn thông thường.

Ví dụ minh họa

1. Tạo collection với dữ liệu

> db.soSanhTruong.insertOne({"GiaTri1":30,"GiaTri2":40});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c99ed2d6669774125246e") }
> db.soSanhTruong.insertOne({"GiaTri1":60,"GiaTri2":70});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c99f62d6669774125246f") }
> db.soSanhTruong.insertOne({"GiaTri1":160,"GiaTri2":190});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c99ff2d66697741252470") }
> db.soSanhTruong.insertOne({"GiaTri1":200,"GiaTri2":160});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c9a0b2d66697741252471") }

2. Tìm tài liệu nơi GiaTri1 > GiaTri2

> db.soSanhTruong.find({ $where: "this.GiaTri1 > this.GiaTri2" });

Kết quả:

{ "_id" : ObjectId("5c9c9a0b2d66697741252471"), "GiaTri1" : 200, "GiaTri2" : 160 }

3. Tìm tài liệu nơi GiaTri1 < GiaTri2

> db.soSanhTruong.find({ $where: "this.GiaTri1 < this.GiaTri2" });

Kết quả:

{ "_id" : ObjectId("5c9c99ed2d6669774125246e"), "GiaTri1" : 30, "GiaTri2" : 40 }
{ "_id" : ObjectId("5c9c99f62d6669774125246f"), "GiaTri1" : 60, "GiaTri2" : 70 }
{ "_id" : ObjectId("5c9c99ff2d66697741252470"), "GiaTri1" : 160, "GiaTri2" : 190 }

Các phương án thay thế hiệu quả hơn

Từ MongoDB 3.6+, bạn có thể sử dụng $expr kết hợp với các toán tử aggregation để so sánh trường với hiệu suất tốt hơn:

// Tương đương với $where nhưng nhanh hơn
db.soSanhTruong.find({ $expr: { $gt: ["$GiaTri1", "$GiaTri2"] } });
db.soSanhTruong.find({ $expr: { $lt: ["$GiaTri1", "$GiaTri2"] } });

Lưu ý về hiệu suất

  • $where không sử dụng index, phải quét toàn bộ collection
  • $expr có thể tận dụng index trong một số trường hợp
  • Tránh sử dụng $where trên dataset lớn