Mongodb Aggregation Pipelineがよくわかっていなかった


データの結果集計のため、
MongodbAggregation Pipeline を使用していました。
Google 検索の結果のうろ覚えの知識で SQL 感覚で使用したところ、
思った通りの結果が取得できず、小2時間くらい悩んでしまった経過を記載します。
わかってしまえば、ああそうなんだなのですが、思い込みは恐ろしいです。

対象レコード

以下のデータが MongodbCollection に設定されているとします。

{
    "_id" : ObjectId("578cfbe617470e0ee0e5d954"),
    "_target" : "ALL",
    "_classify" : "DMI_SCHEDULED_THREAD_POOL_EXECUTOR_WITH_ZERO_CORE_THREADS",
    "Bug" : {
        "@code" : "Dm"
    },
    "_row_url" : "https://raw.githubusercontent.com/Alluxio/alluxio/31fccef69e8c1e680588bf19c27f08968a497319/build/findbugs/findbugs-exclude.xml",
    "_count" : 20
}
{
    "_id" : ObjectId("578cfbe617470e0ee0e5d955"),
    "_target" : "ALL",
    "_classify" : "DMI_CONSTANT_DB_PASSWORD",
    "Bug" : {
        "@code" : "Dm"
    },
    "_row_url" : "https://raw.githubusercontent.com/Alluxio/alluxio/31fccef69e8c1e680588bf19c27f08968a497319/build/findbugs/findbugs-exclude.xml",
    "_count" : 21
}
{
    "_id" : ObjectId("578cfbe617470e0ee0e5d956"),
    "_target" : "ALL",
    "_classify" : "DMI_EMPTY_DB_PASSWORD",
    "Bug" : {
        "@code" : "Dm"
    },
    "_row_url" : "https://raw.githubusercontent.com/Alluxio/alluxio/31fccef69e8c1e680588bf19c27f08968a497319/build/findbugs/findbugs-exclude.xml",
    "_count" : 22
}
{
    "_id" : ObjectId("578cfbe617470e0ee0e5d957"),
    "_target" : "ALL",
    "_classify" : "DMI_UNSUPPORTED_METHOD",
    "Bug" : {
        "@code" : "Dm"
    },
    "_row_url" : "https://raw.githubusercontent.com/Alluxio/alluxio/31fccef69e8c1e680588bf19c27f08968a497319/build/findbugs/findbugs-exclude.xml",
    "_count" : 23
}

Aggregation データが取得できないクエリ

これで2時間くらい潰しました。

        db.findbugs_file_collect_result.aggregate([
            { $group: {
                        _id: "$_classify" ,
                        "count": { $sum: 1 }
                      }},
            { $match: { "_target" : "ALL" }},
        ]);

aggregate に使用する配列要素 つまり以下の json は、
Pipeline として処理されるため、

            { $group: {
                        _id: "$_classify" ,
                        "count": { $sum: 1 }
                      }}
            { $match: { "_target" : "ALL" }}

に評価が移った際、結果セット【この表現は正しいか不明】内には、
キー _target を持つデータは存在しないということになります。

Aggregation データが取得できるクエリ

$match と、$group を入れ替えることでデータが取得できるようになります。

        db.findbugs_file_collect_result.aggregate([
            { $match: { "_target" : "ALL" }},
            { $group: {
                        _id: "$_classify" ,
                        "count": { $sum: 1 }
                      }}
        ]);

はまりましたが、動作原理はわかりやすいと思いました。
以上です。

コメント