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

複数のフィールドで$unwindを実行してから$groupを実行すると、mongo$sumが合成されます

    これは本当に簡単です。各配列の結果を合計するには、どちらがどちらであるかを識別し、「要素を組み合わせる」だけです。要するに、最初のパイプライン段階から明らかなように、とにかくドキュメントでこれを行う必要があります。

    したがって、MongoDB 2.6以降には、いくつかのヘルパーメソッドがあります。

    db.events.aggregate([
        { "$project": {
            "app_id": 1,
            "event_count": 1,
            "all_events": {
                "$setUnion": [
                    { "$map": {
                        "input": "$events",
                        "as": "el",
                        "in": {
                            "type": "$$el.type",
                            "value": "$$el.value",
                            "class": { "$literal": "A" }
                        }
                    }},
                    { "$map": {
                        "input": "$unique_events",
                        "as": "el",
                        "in": {
                            "type": "$$el.type",
                            "value": "$$el.value",
                            "class": { "$literal": "B" }
                        }
                    }}
                ]
            }
        }},
        { "$unwind": "$all_events" },
        { "$group": {
            "_id": {
                "app_id": "$app_id",
                "class": "$all_events.class",
                "type": "$all_events.type"
            },
            "event_count": { "$sum": "$event_count" },
            "value": { "$sum": "$all_events.value" }
        }},
        { "$group": {
            "_id": "$_id.app_id",
            "event_count": { "$sum": "$event_count" },
            "events": {
                "$push": {
                    "$cond": [
                        { "$eq": [ "$_id.class", "A" ] },
                        { "type": "$_id.type", "value": "$value" },
                        false
                    ]
                }
            },
            "unique_events": {
                "$push": {
                    "$cond": [
                        { "$eq": [ "$_id.class", "B" ] },
                        { "type": "$_id.type", "value": "$value" },
                        false
                    ]
                }
            }
        }},
        { "$project": {
            "event_count": 1,
            "events": { "$setDifference": [ "$events", [false] ] },
            "unique_events": {
                "$setDifference": [ "$unique_events", [false] ]
            }
        }}
    ])
    

    主に $setUnion および $setDifference 演算子。もう1つのケースは、 $mapです。 、配列を適切に処理します。 を使用せずに、配列に対して操作を実行することがすべてです。 $unwind 。ただし、これらはもちろん以前のバージョンで実行できます。もう少し作業が必要です。

    db.events.aggregate([
        { "$unwind": "$events" },
        { "$group": {
            "_id": "$_id",
            "app_id": { "$first": "$app_id" },
            "event_count": { "$first": "$event_count" },
            "events": {
                "$push": {
                    "type": "$events.type",
                    "value": "$events.value",
                    "class": { "$const": "A" }
                }
            },
            "unique_events": { "$first": "$unique_events" }            
        }},
        { "$unwind": "$unique_events" },
        { "$group": {
            "_id": "$_id",
            "app_id": { "$first": "$app_id" },
            "event_count": { "$first": "$event_count" },
            "events": { "$first": "$events" },
            "unique_events": {
                "$push": {
                    "type": "$unique_events.type",
                    "value": "$unique_events.value",
                    "class": { "$const": "B" }
                }
            }
        }},
        { "$project": {
            "app_id": 1,
            "event_count": 1,
            "events": 1,
            "unique_events": 1,
            "type": { "$const": [ "A","B" ] }
        }},
        { "$unwind": "$type" },
        { "$unwind": "$events" },
        { "$unwind": "$unique_events" },
        { "$group": {
            "_id": "$_id",
            "app_id": { "$first": "$app_id" },
            "event_count": { "$first": "$event_count" },
            "all_events": {
                "$addToSet": {
                    "$cond": [
                         { "$eq": [ "$events.class", "$type" ] },
                         {
                             "type": "$events.type",
                             "value": "$events.value",
                             "class": "$events.class"
                         },
                         {
                             "type": "$unique_events.type",
                             "value": "$unique_events.value",
                             "class": "$unique_events.class"
                         }
                    ]
                }
            }
        }},
        { "$unwind": "$all_events" },
       { "$group": {
            "_id": {
                "app_id": "$app_id",
                "class": "$all_events.class",
                "type": "$all_events.type"
            },
            "event_count": { "$sum": "$event_count" },
            "value": { "$sum": "$all_events.value" }
        }},
        { "$group": {
            "_id": "$_id.app_id",
            "event_count": { "$sum": "$event_count" },
            "events": {
                "$push": {
                    "$cond": [
                        { "$eq": [ "$_id.class", "A" ] },
                        { "type": "$_id.type", "value": "$value" },
                        false
                    ]
                }
            },
            "unique_events": {
                "$push": {
                    "$cond": [
                        { "$eq": [ "$_id.class", "B" ] },
                        { "type": "$_id.type", "value": "$value" },
                        false
                    ]
                }
            }
        }},
        { "$unwind": "$events" },
        { "$match": { "events": { "$ne": false } } },
        { "$group": {
            "_id": "$_id",
            "event_count": { "$first": "$event_count" },
            "events": { "$push": "$events" },
            "unique_events": { "$first": "$unique_events" }
        }},
        { "$unwind": "$unique_events" },
        { "$match": { "unique_events": { "$ne": false } } },
        { "$group": {
           "_id": "$_id",
            "event_count": { "$first": "$event_count" },
            "events": { "$first": "$events" },
            "unique_events": { "$push": "$unique_events" }
        }}
    ])
    

    これにより、各配列が「合計」された状態で必要な結果が得られ、マスターの「event_count」でも正しい結果が得られます。

    おそらく、これらの配列の両方を、示されているようにパイプラインで使用されているものと同様の識別子と組み合わせることを検討する必要があります。この部分は作業の半分です。残りの半分は、最高のアプリケーションパフォーマンスを得るために、事前に集計された結果をコレクションのどこかに保存する必要があると考えています。



    1. MongoDBを使用した間違った距離計算

    2. Mongo DBにはインメモリモードがありますか?

    3. 単一のプロパティ_idのみを返します

    4. マングースに生息する