6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Elasticsearchで日付の範囲の集約クエリを書く

Last updated at Posted at 2022-08-12

自力で書こうとして、「あれ?どう書くんだっけ?」となったので備忘録

集約クエリについて

Elsticseaechでは、通常の検索クエリに合わせて集約のクエリを書くことができます(下記にサンプル)。

qiitaで検索した記事の検索結果に対してタグの集約を合わせて返す場合のクエリの例
# GET /articles/_search
{
  "_source": [
    "id",
    "body"
  ],
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "fields": [
              "title",
              "title.ngram",
              "body",
              "body.ngram"
            ],
            "query": "qiita",
            "type": "phrase",
            "operator": "and"
          }
        }
      ]
    }
  },
  "sort": [
    "_score"
  ],
  "aggs": {
    "tags": {
      "terms": {
        "field": "tag"
      }
    }
  }
}
クエリ中の`aggs`から始まる下記の部分で`tags`というkeyで、indexの中のヒットするコンテンツからtagフィールドを精査してくれます。
  "aggs": {
    "tags": {
      "terms": {
        "field": "tag"
      }
    }
  }

そして、検索結果と合わせて下記のようにチュートリアルタグがついた記事が48件あった、などのように返してくれるようになっています。

{
  "aggs": {
    "tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 10,
      "buckets": [
        {
          "key": "チュートリアル",
          "doc_count": 48
        },
        {
          "key": "aws",
          "doc_count": 1
        },
        #(中略)
        {
          "key": "infrastructure",
          "doc_count": 1
        }
      ]
    }
  }
}

○○日以内に作られた記事の数を知りたい

では、タグと同じように、日付で集計する場合はどのように書くとよいでしょう?
今回は7日以内、30日以内、365日以内に作られた記事の数が欲しい場合を考えます。
また、indexにはdate型のcreated_atが入っています。

Date range aggregationを使おう

Date range aggregationを下記のように使うことで、時間をいい感じに集計することができます。

{
  "aggs": {
    "date": {
      "date_range": {
        "field": "created_at",
        "format": "yyyy-MM-dd'T'HH:mm:ssZ",
        "ranges": [
          {
            "from": "now-168h"
          },
          {
            "from": "now-720h"
          },
          {
            "from": "now-8760h"
          }
        ]
      }
    }
  }
}

ポイントはfromの部分で、now-時間の形式で○○前からの記事数を集めることができます。
下記のような形式で帰ってきます。

{
  "aggregations": {
    "date": {
      "buckets": [
        {
          "key": "2021-08-12T03:25:33+0000-*",
          "from": 1628738733198,
          "from_as_string": "2021-08-12T03:25:33+0000",
          "doc_count": 55
        },
        {
          "key": "2022-07-13T03:25:33+0000-*",
          "from": 1657682733198,
          "from_as_string": "2022-07-13T03:25:33+0000",
          "doc_count": 2
        },
        {
          "key": "2022-08-05T03:25:33+0000-*",
          "from": 1659669933198,
          "from_as_string": "2022-08-05T03:25:33+0000",
          "doc_count": 0
        }
      ]
    }
  }
}

今回はhを指定しているのでそれぞれ(指定したい日付範囲)*24を入れてあげればいいわけですね。

下記のように書いてもいいでしょう。

{
  "aggs": {
    "date": {
      "date_range": {
        "field": "created_at",
        "format": "yyyy-MM-dd'T'HH:mm:ssZ",
        "ranges": [
          {
            "from": "now-1w"
          },
          {
            "from": "now-30d"
          },
          {
            "from": "now-365d"
          }
        ]
      }
    }
  }
}
6
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?