集約の実行

edit

アグリゲーションを使用すると、データの統計情報をグループ化したり展開したりすることができます。集約について考える上で最も簡単な方法は、集約とSQL GROUP BY機能およびSQL集約機能を同等とみなすことです。Elasticsearchでは、ヒットを返す検索を実行すると同時に、ヒットとは別の集約された結果を1つの応答にまとめて返すことができます。これは、クエリと複数の集約を実行し一回で両方(またはいずれか)の操作から結果を得ることができ、簡潔で単純化されたAPIを使用してネットワークの往復を回避するという点で、非常に強力で効率的です。

まず、次の例はすべての口座を州ごとにグループ化して、数を降順にソート(デフォルト)した上位10個(デフォルト)の州を返します。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

SQLでは、上記の集約は次の考え方と類似しています。

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

次のような応答が返ります(部分的に表示)。

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

口座が`ID`(アイダホ)に27個、TX(テキサス)に27個、AL(アラバマ)に25個などとなっていることがわかります。

応答に集約結果だけを表示するようにするため、`size=0`を設定して検索ヒットを表示しないようにします。

前の集約を基にして、次の例は州ごとに平均の口座残高を計算します(数を降順にソートした上位10個の州)。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

`average_balance`集約が`group_by_state`集約にどうネストされているかに注目してください。これは、すべての集約に共通のパターンです。集約内に集約を任意にネストして、ピボットされた必要な要約をデータから抽出できます。

では、前の集約を基にして、平均残高を降順にソートしてみましょう。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

次の例は、年齢層(20~29歳、30~39歳、および40~49歳)でグループ化してから性別でグループ化し、年齢層ごと、性別ごとの平均口座残高を得る方法を示しています。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

ここでは説明しませんが、ほかにも集約の機能はたくさんあります。さらに試してみたい場合は、まず​集約リファレンスガイド​を読むことをお勧めします。