sql >> データベース >  >> NoSQL >> MongoDB

キーへのMongoDB集約グループ配列:合計値

    実際のフォームの場合、つまり「type」の可能な値を実際に知っていると仮定すると、2つの $ group ステージと $ cond 演算子:

    db.types.aggregate([
        { "$group": {
             "_id": {
                 "stat": "$stat",
                 "type": "$type"
             },
             "count": { "$sum": 1 }
        }},
        { "$group": {
            "_id": "$_id.stat",
            "type1": { "$sum": { "$cond": [
                { "$eq": [ "$_id.type", 1 ] },
                "$count",
                0
            ]}},
            "type2": { "$sum": { "$cond": [
                { "$eq": [ "$_id.type", 2 ] },
                "$count",
                0
            ]}},
            "type3": { "$sum": { "$cond": [
                { "$eq": [ "$_id.type", 3 ] },
                "$count",
                0
            ]}}
        }}
    ])
    

    これは正確に:

    { "_id" : "foobar", "type1" : 2, "type2" : 1, "type3" : 1 }
    

    私は実際には、2つの $を使用したより動的な形式を好みます。グループ ただし、ステージ:

    db.types.aggregate([
        { "$group": {
             "_id": {
                 "stat": "$stat",
                 "type": "$type"
             },
             "count": { "$sum": 1 }
        }},
        { "$group": {
            "_id": "$_id.stat",
            "types": { "$push": {
                "type": "$_id.type",
                "count": "$count"
            }}
        }}
    ])
    

    同じ出力ではありませんが、機能的で値に柔軟に対応します:

    {
        "_id" : "foobar",
        "types" : [
                {
                        "type" : 3,
                        "count" : 1
                },
                {
                        "type" : 2,
                        "count" : 1
                },
                {
                        "type" : 1,
                        "count" : 2
                }
        ]
    }
    

    それ以外の場合、同じ出力形式が必要であるが柔軟なフィールドが必要な場合は、いつでもmapReduceを使用できますが、まったく同じ出力ではありません。

    db.types.mapReduce(
        function () {
    
            var obj = { };
    
            var key = "type" + this.type;
            obj[key] = 1;
    
            emit( this.stat, obj );
    
        },
        function (key,values) {
    
            var obj = {};
    
            values.forEach(function(value) {
                for ( var k in value ) {
                    if ( !obj.hasOwnProperty(k) )
                        obj[k] = 0;
                    obj[k]++;
                }
            });
    
            return obj;
    
        },
        { "out": { "inline": 1 } }
    )
    

    そして典型的なmapReduceスタイルで:

       "results" : [
                {
                        "_id" : "foobar",
                        "value" : {
                                "type1" : 2,
                                "type2" : 1,
                                "type3" : 1
                        }
                }
        ],
    

    しかし、それらはあなたの選択肢です



    1. マングースにネストされたエンティティを取り込む方法は?

    2. Spring Data MongoDB –インデックス、アノテーション、コンバーター

    3. セカンダリノードからプライマリにセカンダリをプロモートします

    4. マングーススキーマのネストされたオブジェクト