UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Elasticsearch】Aggregateしたものの中で条件にマッチしたものだけでsumしたい

ElasticsearchのAggregationで集約するときに、ある条件にマッチしたドキュメント(レコード)だけでsumしたい

例えば、物件ドキュメントが以下のような物件タイプというフィールドを持っている場合

  • 物件タイプ: アパート、マンション、一軒家、ホテル、コンドミニアム、カプセルホテル

それぞれ何件あるかは次のようなクエリを書けば取得できるのだが、

// request
{
    "aggs": {
        "listingType": {
            "terms": {
                "field": "listingType"
            }
        }
    }
}
// response
{
    "aggregations": {
        "listingType": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "アパート",
                    "doc_count": 31195
                },
                {
                    "key": "マンション",
                    "doc_count": 23500
                },
                ...

                {
                    "key": "カプセルホテル",
                    "doc_count": 1195
                },
            ]
        }
    }
}

カプセルホテルホテルとして足し合わせてカウント、コンドミニアムアパートとして足し合わせてカウントしたいときにどうすればよいか

sumとscriptを使う

これが参考になったのだがsumとscriptを使うのがよさそう

stackoverflow.com

以下のようなクエリで集約することができた

// request
{
    "aggs": {
        "apartment": {
            "sum" {
                "script": {
                    "lang": "painless",
                    "source": "(doc['listingType'].value == 'アパート' || doc['listingType'].value == 'コンドミニアム') ? 1 : 0"
                 }
             }
        },
        "hotel": {
            "sum" {
                "script": {
                    "lang": "painless",
                    "source": "(doc['listingType'].value == 'ホテル' || doc['listingType'].value == 'カプセルホテル') ? 1 : 0"
                 }
             }
        }
    }
}// response
{
    "aggregations": {
        "apartment": {
            "value": 54030
        },
        "hotel": {
            "value": 45230
        },
    }
}