query - mysql to mongodb
$ Condicional suma en MongoDB (3)
A partir de la versión 3.4, podemos usar el operador $switch
que permite el procesamiento de condiciones lógicas en la etapa $group
. Por supuesto, todavía necesitamos usar el acumulador de $sum
para devolver la suma.
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 aún no ha migrado su mongod
a 3.4 o más reciente, tenga en cuenta que la etapa de $project
en esta answer es redundante porque el operador de $cond
devuelve un valor numérico, lo que significa que puede $group
sus documentos y aplicar la $sum
a los $cond
expresión.
Esto mejorará el rendimiento en su aplicación, especialmente para grandes colecciones.
db.Sentiments.aggregate(
[
{ ''$group'': {
''_id'': ''$Company'',
''PosSentiment'': {
''$sum'': {
''$cond'': [
{ ''$gt'': [''$Sentiment'', 0]},
''$Sentiment'',
0
]
}
},
''NegSentiment'': {
''$sum'': {
''$cond'': [
{ ''$lt'': [''$Sentiment'', 0]},
''$Sentiment'',
0
]
}
}
}}
]
)
Considera una colección de Sentimientos con los siguientes documentos:
{ "Company": "a", "Sentiment" : 2 }
{ "Company": "a", "Sentiment" : 3 }
{ "Company": "a", "Sentiment" : -1 }
{ "Company": "a", "Sentiment" : -5 }
La consulta de agregación produce:
{ "_id" : "a", "SumPosSenti" : 5, "SumNegSenti" : -6 }
Mi colección en mongodb es similar a la siguiente tabla en SQL:
Sentimientos (Empresa, Sentimiento)
Ahora, necesito ejecutar una consulta como esta:
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
¿Qué debo hacer para escribir esta consulta en Mongo? Estoy atascado en la siguiente consulta:
db.Sentiments.aggregate(
{ $project: {_id:0, Company:1, Sentiment: 1} },
{ $group: {_id: "$Company", SumPosSenti: {$sum: ? }, SumNegSenti: {$sum: ? } } }
);
Como Sammaye sugirió, debe usar el operador de proyección de agregación $cond
para hacer esto:
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''}
}});
Explicando los fragmentos de código anteriores, que usa la sintaxis de matriz:
PosSentiment: {$cond: [{$gt: [''$Sentiment'', 0]}, ''$Sentiment'', 0]}
es igual a:
PosSentiment: {$cond: { if: {$gt: [''$Sentiment'', 0]}, then: ''$Sentiment'', else: 0} }
La sintaxis de la matriz resume la larga sintaxis de solo { $cond: [if, then, else] }