Ma collection dans mongodb est similaire au tableau suivant en SQL:
Sentiments (Société, Sentiment)
Maintenant, je dois exécuter une requête comme celle-ci:
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
Que dois-je faire pour écrire cette requête en mongo? Je suis bloqué à la requête suivante:
db.Sentiments.aggregate(
{ $project: {_id:0, Company:1, Sentiment: 1} },
{ $group: {_id: "$Company", SumPosSenti: {$sum: ? }, SumNegSenti: {$sum: ? } } }
);
Comme Sammaye l'a suggéré, vous devez utiliser l'opérateur de projection d'agrégation $cond
pour ce faire:
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'}
}});
À partir de la version 3.4, nous pouvons utiliser l'opérateur $switch
qui permet le traitement des conditions logiques dans l'étape $group
. Bien sûr, nous devons encore utiliser le $sum
accumulator pour renvoyer la somme.
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
}
}
}
}}
]
)
Si vous n'avez pas encore migré votre mongod
vers 3.4 ou plus récente, notez que l'étape $project
de ce answer est redondante car l'opérateur $cond
renvoie une valeur numérique, ce qui signifie que vous pouvez $group
vos documents et appliquez $sum
à l’expression $cond
.
Cela améliorera les performances de votre application, en particulier pour les grandes collections.
db.Sentiments.aggregate(
[
{ '$group': {
'_id': '$Company',
'PosSentiment': {
'$sum': {
'$cond': [
{ '$gt': ['$Sentiment', 0]},
'$Sentiment',
0
]
}
},
'NegSentiment': {
'$sum': {
'$cond': [
{ '$lt': ['$Sentiment', 0]},
'$Sentiment',
0
]
}
}
}}
]
)
Considérons une collection Sentiments avec les documents suivants:
{ "Company": "a", "Sentiment" : 2 }
{ "Company": "a", "Sentiment" : 3 }
{ "Company": "a", "Sentiment" : -1 }
{ "Company": "a", "Sentiment" : -5 }
La requête d'agrégation produit:
{ "_id" : "a", "SumPosSenti" : 5, "SumNegSenti" : -6 }
Expliquant les extraits ci-dessus, qui utilise la syntaxe de tableau:
PosSentiment: {$cond: [{$gt: ['$Sentiment', 0]}, '$Sentiment', 0]}
est égal à:
PosSentiment: {$cond: { if: {$gt: ['$Sentiment', 0]}, then: '$Sentiment', else: 0} }
La syntaxe du tableau récapitule la syntaxe longue en seulement { $cond: [if, then, else] }