62

mongodbの私のコレクションは、SQLの次の表に似ています。

センチメント(会社、センチメント)

次に、次のようなクエリを実行する必要があります。

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

このクエリをMongoで作成するにはどうすればよいですか?私は次のクエリで立ち往生しています:

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

3 に答える 3

77

$condSammayeが提案したように、これを行うには、集計射影演算子を使用する必要があります。

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'}
    }});
于 2012-12-31T14:43:26.460 に答える
53

バージョン3.4から、ステージ$switchで論理条件処理を可能にする演算子を使用できるようになりました。$groupもちろん$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 
                    } 
                }
            }
        }}
    ]
)

mongod3.4以降にまだ移行していない場合は、演算子が数値を返すため、この回答$projectの段階が冗長であることに注意してください。これは、ドキュメントを作成して式に適用できることを意味します。$cond$group$sum$cond

これにより、特に大規模なコレクションの場合、アプリケーションのパフォーマンスが向上します。

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

次のドキュメントを含むコレクションSentimentsについて考えてみます。

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

集計クエリは以下を生成します。

{ "_id" : "a", "SumPosSenti" : 5, "SumNegSenti" : -6 }
于 2016-08-06T07:10:19.100 に答える
7

配列構文を使用する上記のスニペットを説明します。

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

等しい:

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

配列構文は、長い構文を次のように要約します。{ $cond: [if, then, else] }

于 2018-02-23T21:51:24.317 に答える