My collection in mongodb is similar to the following table in SQL:
Sentiments(Company,Sentiment)
Now, I need to execute a query like this:
SELECT Company, SUM(CASE WHEN Sentiment >0 THEN Sentiment ELSE 0 END) AS SumPosSenti, SUM(CASE WHEN Sentiment <0 THEN Sentiment ELSE 0 END) AS SumNegSenti FROM Sentiments GROUP BY Company What should I do to write this query in Mongo? I am stuck at the following query:
db.Sentiments.aggregate( { $project: {_id:0, Company:1, Sentiment: 1} }, { $group: {_id: "$Company", SumPosSenti: {$sum: ? }, SumNegSenti: {$sum: ? } } } );
Calculates and returns the collective sum of numeric values.
The $$ROOT variable contains the source documents for the group. If you'd like to just pass them through unmodified, you can do this by $pushing $$ROOT into the output from the group.
The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields. The $project specifications have the following forms: Form. Description.
$sum operator returns the sum of all numeric values of documents in the collection in MongoDB. Above will create collection (or table) (if collection already exists it will insert documents in it). Step 2.1 - We will group employee by firstName and find sum of salary of each group.
As Sammaye suggested, you need to use the $cond aggregation projection operator to do this:
db.Sentiments.aggregate( { $project: { _id: 0, Company: 1, PosSentiment: {$cond: [{$gt: ['$Sentiment', 0]}, '$Sentiment', 0]}, NegSentiment: {$cond: [{$lt: ['$Sentiment', 0]}, '$Sentiment', 0]} }}, { $group: { _id: "$Company", SumPosSentiment: {$sum: '$PosSentiment'}, SumNegSentiment: {$sum: '$NegSentiment'} }});
Starting from version 3.4, we can use the $switch operator which allows logical condition processing in the $group stage. Of course we still need to use the $sum accumulator to return the sum.
db.Sentiments.aggregate( [ { "$group": { "_id": "$Company", "SumPosSenti": { "$sum": { "$switch": { "branches": [ { "case": { "$gt": [ "$Sentiment", 0 ] }, "then": "$Sentiment" } ], "default": 0 } } }, "SumNegSenti": { "$sum": { "$switch": { "branches": [ { "case": { "$lt": [ "$Sentiment", 0 ] }, "then": "$Sentiment" } ], "default": 0 } } } }} ] ) If you have not yet migrated your mongod to 3.4 or newer, then note that the $project stage in this answer is redundant because the $cond operator returns a numeric value which means that you can $group your documents and apply $sum to the $cond expression.
This will improve the performance in your application especially for large collection.
db.Sentiments.aggregate( [ { '$group': { '_id': '$Company', 'PosSentiment': { '$sum': { '$cond': [ { '$gt': ['$Sentiment', 0]}, '$Sentiment', 0 ] } }, 'NegSentiment': { '$sum': { '$cond': [ { '$lt': ['$Sentiment', 0]}, '$Sentiment', 0 ] } } }} ] ) Consider a collection Sentiments with the following documents:
{ "Company": "a", "Sentiment" : 2 } { "Company": "a", "Sentiment" : 3 } { "Company": "a", "Sentiment" : -1 } { "Company": "a", "Sentiment" : -5 } The aggregation query produces:
{ "_id" : "a", "SumPosSenti" : 5, "SumNegSenti" : -6 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With