У меня уже есть решение, но я смотрю на решение, которое выполняет всю работу на MongoServer (потому что я думаю, что это будет быстрее и потребляет меньше памяти)
У меня есть метод класса, как:
function getTotalOutstandingAmount(){
$outstandingAmount = 0;
$subs = $this->mongo->selectCollection('SmsSubscriptions');
$activeSubsctiptions = $subs->find(array('Status' => 1, '$where' => "this.SubscriptionPayments < this.SubscriptionTotal"));
foreach ($activeSubsctiptions AS $sub){
$outstandingAmount += $sub['SubscriptionTotal'] - $sub['SubscriptionPayments'];
}
return $outstandingAmount;
}
Теперь есть способ расчета суммы разностей двух полей с использованием aggregate
метод MongoDB? Есть ли другой, более эффективный способ сделать это?
Подход агрегации должен иметь такой конвейер:
db.SmsSubscriptions.aggregate([
{
"$project": {
"outstandingAmount": {
"$subtract": ["$SubscriptionTotal", "$SubscriptionPayments"]
},
"Status": 1
}
},
{ "$match": { "Status": 1, "outstandingAmount": { "$gt": 0 } } },
{
"$group": {
"_id": null,
"totalOutstandingAmount": { "$sum": "$outstandingAmount" }
}
}
])
Эквивалентная реализация примера PHP:
$ops = array(
array(
"$project" => array(
"Status" => 1,
"outstandingAmount" => array(
"$subtract" => array("$SubscriptionTotal", "$SubscriptionPayments")
)
)
)
),
array(
"$match" => array(
"Status" => 1,
"outstandingAmount" => array("$gt" => 0)
)
),
array(
"$group" => array(
"_id" => null,
"totalOutstandingAmount" => array("$sum" => "$outstandingAmount" )
)
)
);
$results = $this->mongo->selectCollection('SmsSubscriptions')->aggregate($ops);
Других решений пока нет …