क्वेरी
यह एकत्रीकरण ढांचे का उपयोग करके किया जा सकता है . अगली एकत्रीकरण पाइपलाइन पर विचार करें
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) */
]);
परिणाम
स्पष्टीकरण
इसके पीछे मूल विचार सहायक सरणी . का निर्माण करना है संग्रह में प्रत्येक दस्तावेज़ के लिए (चरण 1-3 )
{ "_id" : 1, "c" : 2 } -> cs = [ 2 ]
{ "_id" : 2, "c" : 6 } -> cs = [ 2, 6 ]
{ "_id" : 3, "c" : 1 } -> cs = [ 2, 6, 1 ]
$slice
का इस्तेमाल करके
सरणी एकत्रीकरण ऑपरेटर और फिर इसे इसमें शामिल सभी तत्वों के योग से बदलें (चरण 4-5 )
{ "_id" : 1, "c" : 2 } -> csum = 2
{ "_id" : 2, "c" : 6 } -> csum = 8
{ "_id" : 3, "c" : 1 } -> csum = 9
$unwind
का इस्तेमाल करके
स्टेज और $sum
समूह संचायक ऑपरेटर ।
फिर csum >= C
. के साथ दस्तावेज़ों की एक और सहायक सरणी बनाएं (चरण 6 )
/* Ex. (C = 8) */
gteC = [ { "_id" : 3, "c" : 1, "csum" : 9 }, { "_id" : 2, "c" : 6, "csum" : 8 } ]
अंतिम चरण csum <= Min { gteC.csum }
के साथ सभी दस्तावेज़ पुनर्प्राप्त करना है . यह $filter
का उपयोग करके किया जाता है
सरणी एकत्रीकरण ऑपरेटर (चरण 7 )।
हालांकि, मैं नहीं हूं सुनिश्चित करें कि यह सबसे कुशल है आप जो चाहते हैं उसे प्राप्त करने के लिए एकत्रीकरण पाइपलाइन (किसी भी सुधार सुझावों के लिए आभारी होंगे)।
PS क्वेरी का परीक्षण करने से पहले संग्रह का नाम बदलना और SET_DESIRED_VALUE_FOR_C_HERE को बदलना न भूलें।