Truy vấn
Nó có thể được thực hiện bằng cách sử dụng khung tổng hợp . Xem xét quy trình tổng hợp tiếp theo
db.collectionName.aggregate([
{
$group:
{
"_id": null,
"ds": { $push: "$$ROOT" },
"cs": { $push: "$c" }
}
}, /* (1) */
{ $unwind: "$ds" }, /* (2) */
{
$project:
{
"_id": "$ds._id",
"c": "$ds.c",
"cs": { $slice: [ "$cs", "$ds._id" ] }
}
}, /* (3): */
{ $unwind: "$cs" }, /* (4) */
{
$group:
{
"_id": "$_id",
"c": { $first: "$c" },
"csum": { $sum: "$cs" }
}
}, /* (5) */
{
$group:
{
"_id": null,
"ds": { $push: "$$ROOT" },
"gteC":
{
$push:
{
$cond:
{
if: { "$gte": [ "$csum", SET_DESIRED_VALUE_FOR_C_HERE ] },
then: "$$ROOT",
else: { }
}
}
}
}
}, /* (6) */
{
$project:
{
"_id": 0,
"docs":
{
$filter:
{
input: "$ds",
"as": "doc",
cond: { $lte: [ "$$doc.csum", { $min: "$gteC.csum" } ] }
}
}
}
}, /* (7) */
{ $unwind: "$docs" }, /* (8) */
{ $project: { "_id": "$docs._id", "c": "$docs.c" } } /* (9) */
]);
Kết quả
Giải thích
Ý tưởng cơ bản đằng sau nó là xây dựng mảng trợ giúp cho mỗi tài liệu trong bộ sưu tập ( giai đoạn 1-3 )
{ "_id" : 1, "c" : 2 } -> cs = [ 2 ]
{ "_id" : 2, "c" : 6 } -> cs = [ 2, 6 ]
{ "_id" : 3, "c" : 1 } -> cs = [ 2, 6, 1 ]
sử dụng $slice
toán tử tổng hợp mảng và sau đó thay thế nó bằng tổng tất cả các phần tử mà nó chứa ( giai đoạn 4-5 )
{ "_id" : 1, "c" : 2 } -> csum = 2
{ "_id" : 2, "c" : 6 } -> csum = 8
{ "_id" : 3, "c" : 1 } -> csum = 9
sử dụng $unwind
giai đoạn và $sum
toán tử bộ tích lũy nhóm .
Sau đó, tạo một mảng tài liệu trợ giúp khác với csum >= C
( giai đoạn 6 )
/* Ex. (C = 8) */
gteC = [ { "_id" : 3, "c" : 1, "csum" : 9 }, { "_id" : 2, "c" : 6, "csum" : 8 } ]
Bước cuối cùng là truy xuất tất cả tài liệu bằng csum <= Min { gteC.csum }
. Điều này được thực hiện bằng cách sử dụng $filter
toán tử tổng hợp mảng ( giai đoạn 7 ).
Tuy nhiên, tôi không chắc chắn đây là hiệu quả nhất quy trình tổng hợp (sẽ biết ơn nếu có bất kỳ đề xuất cải tiến nào) để đạt được những gì bạn muốn.
Tái bút Trước khi kiểm tra truy vấn, đừng quên thay đổi tên của bộ sưu tập và thay thế SET_DESIRED_VALUE_FOR_C_HERE.