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

So sánh nhiều thuộc tính trong MongoDB với $where

Toán tử $where cho phép chạy JavaScript expression tùy ý để so sánh nhiều trường hoặc tính toán phức tạp. Cảnh báo: Chậm, không dùng index, nguy hiểm injection nếu input từ user.

Dữ liệu mẫu

> db.demo223.insertOne({"Scores":[56,78]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4ca03d395bdc2134730") }
> db.demo223.insertOne({"Scores":[88,45]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4d103d395bdc2134731") }
> db.demo223.insertOne({"Scores":[98,79]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4d803d395bdc2134732") }

Truy vấn $where

Tìm document có Scores[0] > Scores[1]:

> db.demo223.find({ $where : "this.Scores[0] > this.Scores[1]" });

Kết quả

{ "_id" : ObjectId("5e3ee4d103d395bdc2134731"), "Scores" : [ 88, 45 ] }
{ "_id" : ObjectId("5e3ee4d803d395bdc2134732"), "Scores" : [ 98, 79 ] }

Giải thích:

  • this tham chiếu đến document hiện tại
  • this.Scores[0] truy cập phần tử đầu mảng
  • JavaScript engine đánh giá expression cho mỗi document

⚠️ Hạn chế nghiêm trọng:

  • Không sử dụng index → full collection scan
  • Chậm hơn nhiều so với query operator chuẩn
  • Rủi ro bảo mật nếu nối chuỗi input user
  • Không hoạt động trong sharded cluster một số trường hợp

Thay thế hiện đại (MongoDB 3.6+): Dùng $expr với aggregation operators:

db.demo223.find({ $expr: { $gt: [ { $arrayElemAt: ["$Scores", 0] }, { $arrayElemAt: ["$Scores", 1] } ] } });

Cách này dùng index, an toàn, nhanh hơn.