I have a collection. I am trying to get an aggregate sum/count of a field in the record. I also need an aggregate sum/count of a nested array field in the record. I am using MongoDB 3.0.0 with Jongo.
Please find my record below:
db.events.insert([{
"eventId": "a21sda2s-711f-12e6-8bcf-p1ff819aer3o", "orgName": "ORG1", "eventName": "EVA2", "eventCost": 5000, "bids": [{ "vendorName": "v1", "bidStatus": "ACCEPTED", "bidAmount": 4400 },{ "vendorName": "v2", "bidStatus": "PROCESSING", "bidAmount": 4900 },{ "vendorName": "v3", "bidStatus": "REJECTED", "bidAmount": "3000" }] }, { "eventId": "4427f318-7699-11e5-8bcf-feff819cdc9f", "orgName": "ORG1", "eventName": "EVA3", "eventCost": 1000, "bids": [ { "vendorName": "v1", "bidStatus": "REJECTED", "bidAmount": 800 }, { "vendorName": "v2", "bidStatus": "PROCESSING", "bidAmount": 900 },{ "vendorName": "v3", "bidStatus": "PROCESSING", "bidAmount": 990 }] }])
I need $eventCount and $eventCost where I aggregate $eventCost field. I get $acceptedCount and $acceptedAmount by aggregating $bids.bidAmount field (with a condition on $bids.bidStatus)
The result I need would be in form:
[
{
"_id" : "EVA2",
"eventCount" : 2,
"eventCost" : 10000,
"acceptedCount" : 2,
"acceptedAmount" : 7400 },
{
"_id" : "EVA3",
"eventCount" : 1,
"eventCost" : 1000 ,
"acceptedCount" : 0,
"acceptedAmount" : 0 },
}]
I am not able to get the result in a single query. Right now I make two Queries A and Query B(refer below) and merge them in my Java Code. I use an $unwind operator in my Query B.
Is there a way I can the achieve the same result, in a single query. I feel all I need is a way to pass the bids[] array downstream for the next operation in the pipeline.
I tried $push operator, but I am not able to figure, a way to push the entire bid[] array downstream.
I don't want to change my record structure, but if there is something intrinsically wrong, I could give it a try. Thanks for all your help.
My Solution
Query A:
db.events.aggregate([
{$group: {
_id: "$eventName",
eventCount: {$sum: 1}, // Get count of all events
eventCost: {$sum: "$eventCost"} // Get sum of costs
} }
])
Query B:
db.events.aggregate([
{$unwind: "$bids" },
{$group: {
_id: "$eventName",
// Get Count of Bids that have been accepted
acceptedCount:{ $sum:{$cond: [{$eq: ["$bids.bidStatus","ACCEPTED"]} ,1,0] } } ,
// Get Sum of Amounts that have been accepted
acceptedAmount:{$sum:{$cond: [{$eq: ["$bids.bidStatus","ACCEPTED"]} ,"$bids.bidAmount",0]
} } } }
])
Join Query A and QueryB in Java Code.
What I need:
A single DB operation to accomplish the same