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

Sắp xếp theo hiệu chênh lệch phần tử mảng trong MongoDB Aggregate

Sử dụng aggregation pipeline để tính hiệu giữa hai phần tử mảng (ví dụ phần tử cuối và phần tử trước cuối) và sắp xếp theo kết quả đó.

Dữ liệu mẫu

> db.demo155.insertOne({"Scores":[{"Value":45},{"Value":50}]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e354584fdf09dd6d08539e3") }
> db.demo155.insertOne({"Scores":[{"Value":60},{"Value":10}]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e35458efdf09dd6d08539e4") }
> db.demo155.insertOne({"Scores":[{"Value":100},{"Value":95}]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e354599fdf09dd6d08539e5") }

Pipeline aggregate

> db.demo155.aggregate([
...   { "$match": { "Scores.1": { "$exists": true } } },
...   { "$project": {
...     "Scores": "$Scores",
...     "sub": {
...       "$let": {
...         "vars": {
...           "f": { "$arrayElemAt": [ "$Scores", -2 ] },
...           "l": { "$arrayElemAt": [ "$Scores", -1 ] }
...         },
...         "in": { "$subtract": [ "$$l.Value", "$$f.Value" ] }
...       }
...     }
...   }},
...   { "$sort": { "sub": -1 } }
... ])

Kết quả

{ "_id" : ObjectId("5e354584fdf09dd6d08539e3"), "Scores" : [ { "Value" : 45 }, { "Value" : 50 } ], "sub" : 5 }
{ "_id" : ObjectId("5e354599fdf09dd6d08539e5"), "Scores" : [ { "Value" : 100 }, { "Value" : 95 } ], "sub" : -5 }
{ "_id" : ObjectId("5e35458efdf09dd6d08539e4"), "Scores" : [ { "Value" : 60 }, { "Value" : 10 } ], "sub" : -50 }

Giải thích pipeline:

  1. $match: Chỉ giữ tài liệu có ít nhất 2 phần tử trong Scores (kiểm tra Scores.1 tồn tại).
  2. $project: Tạo trường sub bằng cách lấy phần tử -2 (phần tử trước cuối) và -1 (phần tử cuối) qua $arrayElemAt, rồi trừ Value của chúng.
  3. $sort: Sắp xếp giảm dần theo sub.

Cải tiến MongoDB 5.0+: Có thể dùng $getField hoặc $reduce để code ngắn gọn hơn.