Elasticsearchにおける数値および日時範囲クエリの高度な活用方法

範囲クエリの基礎演算子

Elasticsearchにおいて数値や日時を対象とした範囲検索は、`range` クエリを使用して実装します。比較条件を指定するための主要な演算子は以下の通りです。

演算子意味
gteGreater than or equal to(以上)
gtGreater than(より大きい)
lteLess than or equal to(以下)
ltLess than(より小さい)

数値フィールドの範囲検索

特定の数値区間に含まれるドキュメントを取得する際、下限値と上限値を組み合わせることができます。以下は、商品カタログから単価が50元以上かつ150元以下のレコードを抽出する例です。

GET products_catalog/_search
{
  "query": {
    "range": {
      "unit_cost": {
        "gte": 50,
        "lte": 150,
        "boost": 1.5
      }
    }
  }
}

`boost` パラメータは検索スコアに重みを付与する際に使用し、デフォルト値は `1.0` です。

日時フィールドの範囲検索

基本的なクエリ構造

投稿日時やシステムログのタイムスタンプを対象に、相対的な時間帯でフィルタリングすることが可能です。直近24時間以内に生成されたイベントを抽出する例を示します。

GET system_logs/_search
{
  "query": {
    "range": {
      "generated_at": {
        "gte": "now-24h/h",
        "lt": "now/h"
      }
    }
  }
}

Date Math(日付演算)の仕様

Elasticsearchのクエリ文字列では、システム時刻を `now` キーワードで参照できます。固定日時は `||` 記号を接尾辞として付けることで基準日として扱います。これらの値に対して以下の演算子を適用可能です。

  • `+1d`: 1日加算
  • `-2h`: 2時間減算
  • `/M`: 月初めに丸める

サポートされている時間単位は下表の通りです。

単位意味単位意味
yM
wd
h / H時間m
s

演算は基準値のミリ秒単位で行われ、結果が再解釈されます。例えば基準時刻が `2023-05-15T10:30:00` の場合、`now-3d/d` と指定すると、まず3日引き算された後、指定された区間の最初に丸められて `2023-05-12T00:00:00` として評価されます。

境界値の丸め処理(Rounding)の動作規則

範囲の上下限に丸め処理(例:`/d`, `/M`)を適用する際、その条件が「等号を含む(gte/lte)」か「等号を含まない(gt/lt)」かによって、丸め方向が自動的に決定されます。

  • `gt` および `lte`:区間の末尾(最終ミリ秒)に丸められます。
  • `gte` および `lt`:区間の先頭(開始ミリ秒)に丸められます。

これにより、特定の月や日付を完全に含めるか除外するかが意図通りに制御できます。例えば `2023-11-15||/M` を使用した場合、`gt` は11月全体を除外するため `2023-11-30T23:59:59.999Z` となり、`gte` は11月全体を含めるため `2023-11-01T00:00:00Z` として解釈されます。

日付フォーマットのカスタマイズ

`range` クエリ内では、`format` パラメータを指定することでインデックススキーマで定義されたデフォルト形式を上書きできます。複数のフォーマットパターンを `||` で連結して、入力値の柔軟なパースを実現します。

GET news_articles/_search
{
  "query": {
    "range": {
      "published_on": {
        "gte": "03-15-2024",
        "lte": "2025",
        "format": "MM-dd-yyyy||yyyy"
      }
    }
  }
}

指定されたフォーマットに年、月、日のいずれかが欠落している場合、欠落分はUnixエポック(1970年1月1日)の初期値で埋め合わせられます。例えばフォーマットを `yyyy-MM-dd` として `gte: "2024-06"` と指定すると、日付成分が不足しているため `2024-06-01T00:00:00.000Z` として内部変換されます。

タイムゾーンの考慮とUTC標準化

Elasticsearchは内部的に日時データをすべてUTC(協定世界時)で保存・処理します。検索条件に地域固有の時刻を使用する場合は、`time_zone` パラメータでオフセット(例:`+09:00`)を明示し、入力値が自動変換されるように設定します。

GET user_activities/_search
{
  "query": {
    "range": {
      "last_login": {
        "gte": "2024-01-10 08:00:00",
        "lte": "now",
        "format": "yyyy-MM-dd HH:mm:ss",
        "time_zone": "+09:00"
      }
    }
  }
}

上記の例では、JST(UTC+9)の `2024-01-10 08:00:00` がクエリ評価時に `2024-01-10T09:00:00Z` へと変換されます。ただし、`now` キーワードは常にサーバーのシステム時刻(UTC基準)を参照するため、`time_zone` 設定の影響を受けません。この点は動的な現在時刻比較を行う際に注意が必要です。

タグ: Elasticsearch range-query date-math search-api utc-conversion

7月11日 23:39 投稿