$ $ Condizionale in MongoDB

La mia collezione in mongodb è simile alla seguente tabella in SQL:

Sentimenti (Company, sentimento)

Ora, ho bisogno di eseguire una query come questa:

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 

Cosa dovrei fare per scrivere questa query in Mongo? Sono bloccato alla seguente domanda:

 db.Sentiments.aggregate( { $project: {_id:0, Company:1, Sentiment: 1} }, { $group: {_id: "$Company", SumPosSenti: {$sum: ? }, SumNegSenti: {$sum: ? } } } ); 

Come suggerito da Sammaye, è necessario utilizzare l’operatore di proiezione di aggregazione $cond per fare ciò:

 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'} }}); 

A partire dalla versione 3.4, possiamo usare l’operatore $switch che consente l’elaborazione delle condizioni logiche nella fase $group . Ovviamente abbiamo ancora bisogno di usare l’accumulatore $sum per restituire la 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 } } } }} ] ) 

Se non hai ancora migrato il tuo mongod su 3.4 o più recente, nota che la fase $project in questa risposta è ridondante perché l’operatore $cond restituisce un valore numerico che significa che puoi $group tuoi documenti e applicare $sum a $cond espressione.

Ciò migliorerà le prestazioni della tua applicazione, in particolare per la raccolta di grandi dimensioni.

 db.Sentiments.aggregate( [ { '$group': { '_id': '$Company', 'PosSentiment': { '$sum': { '$cond': [ { '$gt': ['$Sentiment', 0]}, '$Sentiment', 0 ] } }, 'NegSentiment': { '$sum': { '$cond': [ { '$lt': ['$Sentiment', 0]}, '$Sentiment', 0 ] } } }} ] ) 

Considera una raccolta Sentimenti con i seguenti documenti:

 { "Company": "a", "Sentiment" : 2 } { "Company": "a", "Sentiment" : 3 } { "Company": "a", "Sentiment" : -1 } { "Company": "a", "Sentiment" : -5 } 

La query di aggregazione produce:

 { "_id" : "a", "SumPosSenti" : 5, "SumNegSenti" : -6 } 

Spiegando i frammenti sopra, che utilizza la syntax dell’array:

 PosSentiment: {$cond: [{$gt: ['$Sentiment', 0]}, '$Sentiment', 0]} 

è uguale a:

 PosSentiment: {$cond: { if: {$gt: ['$Sentiment', 0]}, then: '$Sentiment', else: 0} } 

La syntax dell’array riepiloga la syntax lunga con { $cond: [if, then, else] }