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

So sánh 2 trường (field) trong MongoDB Aggregation với $cmp và $match

Để lọc document dựa trên sự so sánh giữa **2 trường trong cùng document** (ví dụ: FirstValue > SecondValue), dùng $cmp trong $project tạo trường so sánh, sau đó $match trên trường đó.

Cú pháp

db.collection.aggregate([
    { $project: { 
        comparisonResult: { $cmp: [ "$trường1", "$trường2" ] } 
    }},
    { $match: { comparisonResult: { $gt: 0 } } }  // 1: lớn hơn, 0: bằng, -1: nhỏ hơn
]);

Ví dụ minh họa

Tạo collection matchBetweenFieldsDemo:

> db.matchBetweenFieldsDemo.insertOne({ "FirstValue": 40, "SecondValue": 70 });
> db.matchBetweenFieldsDemo.insertOne({ "FirstValue": 20, "SecondValue": 5 });

Hiển thị:

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

Kết quả:

{ "_id" : ..., "FirstValue" : 40, "SecondValue" : 70 }
{ "_id" : ..., "FirstValue" : 20, "SecondValue" : 5 }

Aggregation: Tìm document có FirstValue > SecondValue

> db.matchBetweenFieldsDemo.aggregate([
    { $project: { 
        firstGreaterThanOrNot: { $cmp: [ "$FirstValue", "$SecondValue" ] } 
    }},
    { $match: { firstGreaterThanOrNot: { $gt: 0 } } }
]);

Kết quả: Chỉ document 2 (FirstValue=20 > SecondValue=5).

{ "_id" : ObjectId("..."), "firstGreaterThanOrNot" : 1 }

Giải thích $cmp

  • Trả về 1 nếu giá trị 1 > giá trị 2.
  • Trả về 0 nếu bằng nhau.
  • Trả về -1 nếu giá trị 1 < giá trị 2.
  • So sánh theo [BSON comparison order](https://www.mongodb.com/docs/manual/reference/bson-type-comparison-order/) (type khác nhau cũng so sánh được).

Các toán tử so sánh khác trong Aggregation

Toán tửMô tảVí dụ
$eqBằng nhau{ $eq: ["$a", "$b"] }
$neKhác nhau{ $ne: ["$a", "$b"] }
$gtLớn hơn{ $gt: ["$a", "$b"] }
$gteLớn hơn hoặc bằng{ $gte: ["$a", "$b"] }
$ltNhỏ hơn{ $lt: ["$a", "$b"] }
$lteNhỏ hơn hoặc bằng{ $lte: ["$a", "$b"] }

Lưu ý: Các toán tử $gt, $lt... trong aggregation nhận **mảng 2 phần tử** [expr1, expr2], khác với query filter nhận object { field: { $gt: value } }.

Ví dụ dùng $gt trực tiếp (không cần $cmp)

db.matchBetweenFieldsDemo.aggregate([
    { $match: { $expr: { $gt: [ "$FirstValue", "$SecondValue" ] } } }
]);

Cách này ngắn gọn hơn (MongoDB 3.6+ hỗ trợ $expr trong $match aggregation).