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

MongoDB2.6アグリゲーションフレームワークの改善

    これはVladMihalceaによるゲスト投稿です。 Vladは、ソフトウェア統合、高いスケーラビリティ、および同時実行性の課題に情熱を注ぐソフトウェアアーキテクトです。元の投稿へのリンクは次のとおりです。MongoDBは急速に進化しています。 2.2バージョンでは、Map-Reduceクエリモデルの代わりに集計フレームワークが導入されました。集約されたレポートの生成は、エンタープライズシステムの繰り返しの要件であり、MongoDBはこの点で優れています。初めて使用する場合は、この集計フレームワークの概要、またはパフォーマンスの調整とデータモデリングガイドを確認することをお勧めします。

    非常に高速なMongoDB挿入機能を示しながら、最初に紹介したデータモデルを再利用しましょう:

    {
            "_id" : ObjectId("5298a5a03b3f4220588fe57c"),
            "created_on" : ISODate("2012-04-22T01:09:53Z"),
            "value" : 0.1647851116706831
    }
    

    MongoDB2.6アグリゲーションの機能強化

    2.4バージョンでは、次の集計クエリを実行すると:

    db.randomData.aggregate( [
    {
        $match: {
            "created_on" : {
                $gte : new Date(Date.UTC(2012, 0, 1)),
                $lte : new Date(Date.UTC(2012, 0, 10))
            }
        }
    },
    {
        $group: {
            _id : {
                "minute" : {
                    $minute : "$created_on"
                }
            },
            "values": {
                $addToSet: "$value"
            }
        }
    }]);
    

    16MBの集計結果の制限に達しました:

    {
        "errmsg" : "exception: aggregation result exceeds maximum document size (16MB)",
        "code" : 16389,
        "ok" : 0
    }
    

    MongoDBドキュメントは16MBに制限されており、2.6バージョンより前では、集計結果はBSONドキュメントでした。 2.6バージョンでは、代わりにカーソルに置き換えられました。

    2.6で同じクエリを実行すると、次の結果が得られます。

    db.randomData.aggregate( [
    {
        $match: {
            "created_on" : {
                $gte : new Date(Date.UTC(2012, 0, 1)),
                $lte : new Date(Date.UTC(2012, 0, 10))
            }
        }
    },
    {
        $group: {
            _id : {
                "minute" : {
                    $minute : "$created_on"
                }
            },
            "values": {
                $addToSet: "$value"
            }
        }
    }])
    .objsLeftInBatch();
    14
    

    カーソルベースのobjsLeftInBatchメソッドを使用して集計結果タイプをテストしましたが、16MBの制限が結果全体に適用されなくなりました。カーソル内部の結果は通常のBSONドキュメントであるため、16 MBに制限されていますが、これは以前の全体的な結果の制限よりもはるかに管理しやすくなっています。

    2.6バージョンは、集計メモリの制限にも対応しています。次のような完全なコレクションスキャン:

    db.randomData.aggregate( [
    {
        $group: {
            _id : {
                "minute" : {
                    $minute : "$created_on"
                }
            },
            "values": {
                $addToSet: "$value"
            }
        }
    }])
    .objsLeftInBatch();
    

    次のエラーが発生する可能性があります:

    {
        "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
        "code" : 16945,
        "ok" : 0
    }
    

    これで、allowDiskUseパラメータを使用して大規模な並べ替え操作を実行できるようになりました:

    db.randomData.aggregate( [
    {
        $group: {
            _id : {
                "minute" : {
                    $minute : "$created_on"
                }
            },
            "values": {
                $addToSet: "$value"
            }
        }
    }]
    ,
    {
        allowDiskUse : true
    })
    .objsLeftInBatch();
    

    2.6バージョンでは、新しく追加された$ outステージを使用して、集計結果を別のコレクションに保存できます。

    db.randomData.aggregate( [
    {
        $match: {
            "created_on" : {
                $gte : new Date(Date.UTC(2012, 0, 1)),
                $lte : new Date(Date.UTC(2012, 0, 10))
            }
        }
    },
    {
        $group: {
            _id : {
                "minute" : {
                    $minute : "$created_on"
                }
            },
            "values": {
                $addToSet: "$value"
            }
        }
    },
    {
        $out : "randomAggregates"
    }
    ]);
    db.randomAggregates.count();
    60
    

    いくつか例を挙げると、let、map、condなどの新しい演算子が追加されました。

    次の例では、特定の各イベントエントリの時間情報にAMまたはPMを追加します。

    var dataSet = db.randomData.aggregate( [
    {
        $match: {
            "created_on" : {
                $gte : new Date(Date.UTC(2012, 0, 1)),
                $lte : new Date(Date.UTC(2012, 0, 2))
            }
        }
    },
    {
        $project: {
            "clock" : {
                $let: {
                    vars: {
                        "hour": {
                            $substr: ["$created_on", 11, -1]
                        },
                        "am_pm": { $cond: { if: { $lt: [ {$hour : "$created_on" }, 12 ] } , then: 'AM',else: 'PM'} }
                    },
                    in: { $concat: [ "$$hour", " ", "$$am_pm"] }
                }
            }
        }
    },
    {
        $limit : 10
    }
    ]);
    dataSet.forEach(function(document)  {
        printjson(document);
    });
    

    結果:

    "clock" : "16:07:14 PM"
    "clock" : "22:14:42 PM"
    "clock" : "21:46:12 PM"
    "clock" : "03:35:00 AM"
    "clock" : "04:14:20 AM"
    "clock" : "03:41:39 AM"
    "clock" : "17:08:35 PM"
    "clock" : "18:44:02 PM"
    "clock" : "19:36:07 PM"
    "clock" : "07:37:55 AM"
    

    結論

    MongoDB 2.6バージョンには、一括操作やインデックスの共通部分など、他にも多くの拡張機能が付属しています。 MongoDBは絶えず進化しており、ドキュメントベースのストレージの実行可能な代替手段を提供します。このような開発率で、2013年のデータベースオブザイヤーに選ばれたのも不思議ではありません。


    1. MongoDB-オブジェクト?なぜ集約して_idが必要なのですか

    2. マルチコアCPUでのRedisのパフォーマンス

    3. 一意のキーを追加した後でもMongoDBがドキュメントを複製する

    4. ServiceStack.Redis:接続できません:sPort:50071