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

Truy vấn MongoDB so sánh 2 trường trong cùng document

Để truy vấn so sánh hai trường trong cùng một document MongoDB, bạn sử dụng toán tử $where với biểu thức JavaScript.

Cú pháp

db.collection.find({ 
    $where: "this.field1 operator this.field2" 
})

Ví dụ minh họa

Tạo collection và dữ liệu

> db.queryInSameDocumentsDemo.insertOne({"StudentDetails":{"StudentName":"John"},"NewStudentDetails":{"StudentName":"Carol"}});
{ "acknowledged" : true, "insertedId" : ObjectId("5c90096ed3c9d04998abf017") }
> db.queryInSameDocumentsDemo.insertOne({"StudentDetails":{"StudentName":"Bob"},"NewStudentDetails":{"StudentName":"Bob"}});
{ "acknowledged" : true, "insertedId" : ObjectId("5c900a435705caea966c5573") }

Xem dữ liệu

> db.queryInSameDocumentsDemo.find().pretty();
{
    "_id" : ObjectId("5c90096ed3c9d04998abf017"),
    "StudentDetails" : { "StudentName" : "John" },
    "NewStudentDetails" : { "StudentName" : "Carol" }
}
{
    "_id" : ObjectId("5c900a435705caea966c5573"),
    "StudentName" : "Bob",
    "NewStudentDetails" : { "StudentName" : "Bob" }
}

Trường hợp 1: So sánh bằng (==)

Tìm document có StudentName giống nhau trong cả 2 object lồng nhau:

> db.queryInSameDocumentsDemo.find( { 
    $where: "this.StudentDetails.StudentName == this.NewStudentDetails.StudentName" 
}).pretty();
{
    "_id" : ObjectId("5c900a435705caea966c5573"),
    "StudentDetails" : { "StudentName" : "Bob" },
    "NewStudentDetails" : { "StudentName" : "Bob" }
}

Trường hợp 2: So sánh không bằng (!=)

Tìm document có StudentName khác nhau:

> db.queryInSameDocumentsDemo.find( { 
    $where: "this.StudentDetails.StudentName != this.NewStudentDetails.StudentName" 
}).pretty();
{
    "_id" : ObjectId("5c90096ed3c9d04998abf017"),
    "StudentDetails" : { "StudentName" : "John" },
    "NewStudentDetails" : { "StudentName" : "Carol" }
}

Các phép so sánh hỗ trợ

Toán tử JSÝ nghĩaVí dụ
==Bằng (loose equality)this.a == this.b
===Bằng chặt (strict)this.a === this.b
!=Khác (loose)this.a != this.b
!==Khác chặtthis.a !== this.b
>, <Lớn hơn, nhỏ hơnthis.score > this.passingScore
>=, <=Lớn/nhỏ hơn hoặc bằngthis.age >= this.minAge

Thay thế hiệu năng cao hơn: $expr (MongoDB 3.6+)

Thay vì $where (chạy JS engine, chậm), dùng $expr với aggregation operators:

// So sánh bằng
db.queryInSameDocumentsDemo.find({
    $expr: { $eq: ["$StudentDetails.StudentName", "$NewStudentDetails.StudentName"] }
});

// So sánh không bằng
db.queryInSameDocumentsDemo.find({
    $expr: { $ne: ["$StudentDetails.StudentName", "$NewStudentDetails.StudentName"] }
});

// So sánh số
db.scores.find({
    $expr: { $gt: ["$math", "$physics"] }
});

Ưu điểm của $expr

  • Không dùng JavaScript engine → nhanh hơn đáng kể
  • Có thể dùng index (trong một số trường hợp)
  • An toàn hơn (không injection risk)
  • Hỗ trợ đầy đủ aggregation operators: $add, $subtract, $concat, $substr...
Cảnh báo: $where không dùng được index, quét toàn bộ collection. Chỉ dùng khi $expr không đáp ứng được (logic phức tạp, regex custom, function tùy chỉnh).