Elasticsearch API の使い方

Ashley Innocent

Ashley Innocent

24 3月 2026

Elasticsearch API の使い方

TL;DR

Elasticsearch APIは、大規模な検索と分析を可能にします。ドキュメントをJSONとしてインデックス化し、強力なDSLでクエリを実行し、分析のために結果を集計します。認証にはAPIキーまたは基本認証を使用します。テストにはApidogを使用して、本番クラスターにデプロイする前にインデックスマッピングを検証し、検索クエリをテストし、集計をデバッグします。

はじめに

Elasticsearchは分散型の検索・分析エンジンです。構造化テキスト、ログ、メトリクスなどを処理します。企業はこれをアプリケーションでの全文検索、デバッグのためのログ分析、リアルタイム分析ダッシュボードに利用しています。

ElasticsearchはELKスタック(Elasticsearch、Logstash、Kibana)の中心に位置します。しかし、LogstashなしでAPI経由で直接使用することもできます。

💡
検索機能やログ分析を構築している場合、Apidogはクエリのテスト、マッピングの検証、集計のデバッグに役立ちます。検索テンプレートを保存してチームと共有することもできます。
ボタン

ApidogでElasticsearch APIをテスト - 無料

このガイドを読み終える頃には、以下のことができるようになります。

はじめに

Elasticsearchをローカルで実行する

# Docker
docker run -p 9200:9200 \
  -e "discovery.type=single-node" \
  elasticsearch:8.11.0

# Or download from elastic.co

インストールの検証

curl -X GET "http://localhost:9200"

応答:

{
  "name": "elasticsearch-1",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "abc123",
  "version": {
    "number": "8.11.0",
    "build_flavor": "default"
  },
  "tagline": "You know, for search"
}

認証

Elasticsearch 8.xはデフォルトで認証が必要です。

curl -X GET "http://localhost:9200/_cluster/health" \
  -u elastic:your_password

またはAPIキーを使用します(KibanaまたはAPI経由で作成)。

インデックスとドキュメント

インデックスの作成

curl -X PUT "http://localhost:9200/products" \
  -u elastic:your_password \
  -H "Content-Type: application/json" \
  -d '{
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
    },
    "mappings": {
      "properties": {
        "name": { "type": "text" },
        "price": { "type": "float" },
        "category": { "type": "keyword" },
        "in_stock": { "type": "boolean" },
        "created_at": { "type": "date" }
      }
    }
  }'

ドキュメントのインデックス化

curl -X POST "http://localhost:9200/products/_doc" \
  -u elastic:your_password \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Wireless Headphones",
    "price": 79.99,
    "category": "electronics",
    "in_stock": true,
    "created_at": "2026-03-24T10:00:00Z"
  }'

応答:

{
  "_index": "products",
  "_id": "abc123",
  "_version": 1,
  "result": "created",
  "_seq_no": 0,
  "_primary_term": 1
}

ドキュメントの取得

curl -X GET "http://localhost:9200/products/_doc/abc123" \
  -u elastic:your_password

ドキュメントの更新

curl -X PUT "http://localhost:9200/products/_doc/abc123" \
  -u elastic:your_password \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Wireless Headphones Pro",
    "price": 99.99,
    "category": "electronics",
    "in_stock": true,
    "created_at": "2026-03-24T10:00:00Z"
  }'

ドキュメントの削除

curl -X DELETE "http://localhost:9200/products/_doc/abc123" \
  -u elastic:your_password

一括操作

複数のドキュメントを効率的にインデックス化します。

curl -X POST "http://localhost:9200/products/_bulk" \
  -u elastic:your_password \
  -H "Content-Type: application/x-ndjson" \
  -d '{"index":{"_id":"1"}}
{"name":"Product A","price":10.99,"category":"books","in_stock":true}
{"index":{"_id":"2"}}
{"name":"Product B","price":20.99,"category":"electronics","in_stock":false}
'

検索クエリ

基本的な検索

curl -X GET "http://localhost:9200/products/_search" \
  -u elastic:your_password \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "match": {
        "name": "headphones"
      }
    }
  }'

Boolクエリ

複数の条件を組み合わせる:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "headphones" } }
      ],
      "filter": [
        { "term": { "category": "electronics" } },
        { "range": { "price": { "lte": 100 } } },
        { "term": { "in_stock": true } }
      ]
    }
  }
}

スコアリングによる全文検索

{
  "query": {
    "multi_match": {
      "query": "wireless audio headphones",
      "fields": ["name^2", "description"],
      "type": "best_fields",
      "fuzziness": "AUTO"
    }
  }
}

^2を持つフィールド名は、スコアリングで2倍の重み付けがされます。

フレーズ検索

正確なフレーズを検索します。

{
  "query": {
    "match_phrase": {
      "description": "noise canceling"
    }
  }
}

ワイルドカードと正規表現

{
  "query": {
    "wildcard": {
      "name": "*headphone*"
    }
  }
}

ソート

{
  "query": { "match_all": {} },
  "sort": [
    { "price": "asc" },
    { "_score": "desc" }
  ]
}

ページネーション

{
  "from": 20,
  "size": 10,
  "query": { "match_all": {} }
}

集計

集計は、データ全体の要約統計量を計算します。

カテゴリごとの平均価格

curl -X GET "http://localhost:9200/products/_search" \
  -u elastic:your_password \
  -H "Content-Type: application/json" \
  -d '{
    "size": 0,
    "aggs": {
      "by_category": {
        "terms": { "field": "category" },
        "aggs": {
          "avg_price": { "avg": { "field": "price" } },
          "min_price": { "min": { "field": "price" } },
          "max_price": { "max": { "field": "price" } }
        }
      }
    }
  }'

価格のヒストグラム

{
  "size": 0,
  "aggs": {
    "price_histogram": {
      "histogram": {
        "field": "price",
        "interval": 25
      }
    }
  }
}

日付ヒストグラム

{
  "size": 0,
  "aggs": {
    "sales_over_time": {
      "date_histogram": {
        "field": "created_at",
        "calendar_interval": "month"
      }
    }
  }
}

カーディナリティ(一意のカウント)

{
  "size": 0,
  "aggs": {
    "unique_categories": {
      "cardinality": { "field": "category" }
    }
  }
}

マッピングとアナライザー

フィールドタイプ

タイプ 用途
text 全文検索、分析済み
keyword 正確な値、フィルタリング、ソート
integer, float 数値
boolean 真/偽
date 日付と時刻
object ネストされたJSONオブジェクト
nested オブジェクトの配列(関係を維持する)
geo_point 緯度/経度座標

カスタムアナライザー

特殊なテキスト処理のために:

{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "autocomplete_filter"]
        }
      },
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 20
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "standard"
      }
    }
  }
}

クラスター管理

クラスターの状態

curl -X GET "http://localhost:9200/_cluster/health"

応答:

{
  "cluster_name": "elasticsearch",
  "status": "green",
  "number_of_nodes": 3,
  "active_primary_shards": 25
}

ステータス:

インデックス統計

curl -X GET "http://localhost:9200/_cat/indices?v"

ノード統計

curl -X GET "http://localhost:9200/_nodes/stats"

キャッシュのクリア

curl -X POST "http://localhost:9200/_cache/clear"

Apidogでのテスト

Elasticsearchのクエリは複雑になりがちです。徹底的にテストしましょう。

1. 一般的なクエリの保存

Apidogに検索テンプレートを保存します。

{
  "query": {
    "bool": {
      "must": [
        { "match": { "{{search_field}}": "{{search_term}}" } }
      ],
      "filter": [
        { "range": { "{{price_field}}": { "lte": "{{max_price}}" } } }
      ]
    }
  }
}

2. 応答の検証

pm.test('Search returns results', () => {
  const response = pm.response.json()
  pm.expect(response.hits.total.value).to.be.above(0)
})

pm.test('Aggregations present', () => {
  const response = pm.response.json()
  pm.expect(response.aggregations).to.exist
})

3. 環境の分離

# ローカル
ES_HOST: http://localhost:9200
ES_USER: elastic
ES_PASSWORD: your_password

# 本番
ES_HOST: https://search.yourcompany.com
ES_API_KEY: prod_api_key

ApidogでElasticsearch APIをテスト - 無料

一般的なエラーと解決策

403 Forbidden

原因: 認証失敗または権限不足。

解決策: 認証情報を確認します。APIキーに正しいインデックス権限があるか確認します。

404 index_not_found_exception

原因: インデックスが存在しません。

解決策: まずインデックスを作成するか、自動作成機能を使用します(デフォルトで有効ですが、本番環境では推奨されません)。

circuit_breaking_exception

原因: クエリがメモリを使いすぎている。

解決策: `size`パラメーターを減らす、クエリを簡素化する、結果セットを減らすためにフィルターを追加する。

search_phase_execution_exception

原因: クエリの構文エラー。

解決策: JSONを確認してください。一般的な問題:引用符の欠落、誤ったフィールドパス。

代替案と比較

機能 Elasticsearch OpenSearch Meilisearch Typesense
セットアップ セルフホスト セルフホスト シングルバイナリ シングルバイナリ
検索品質 素晴らしい 良い 素晴らしい 良い
学習曲線 急勾配 急勾配 簡単 簡単
スケーラビリティ 素晴らしい 素晴らしい 良い 良い
クラウド提供 Elastic Cloud OpenSearch Serverless Meilisearch Cloud Typesense Cloud

Elasticsearchには最も多くの機能とコミュニティがあります。MeilisearchとTypesenseは基本的な検索にはよりシンプルです。

実世界でのユースケース

Eコマース検索。小売サイトが10万点の製品をインデックス化します。ユーザーは名前、説明、カテゴリ、価格帯で検索します。入力中にオートコンプリートが製品を提案します。フィルターによってカテゴリと在庫状況で結果を絞り込みます。

アプリケーションログ。DevOpsチームはFilebeat経由でログをElasticsearchに送ります。エンジニアはサービス、重大度、時間範囲でログを検索します。ダッシュボードにはエラー率と応答時間が表示されます。

セキュリティ分析。セキュリティチームはネットワークログをインデックス化します。彼らは疑わしいIPアドレスを検索し、トラフィックパターンを視覚化し、集計によって検出された異常についてアラートを出します。

まとめ

ここで学んだことは次のとおりです。

次のステップ:

  1. Elasticsearchをローカルで実行する
  2. マッピング付きでインデックスを作成する
  3. テストドキュメントをいくつかインデックス化する
  4. 検索クエリを作成する
  5. 集計を試す

ApidogでElasticsearch APIをテスト - 無料

ボタン

FAQ

ElasticsearchとSolrの違いは何ですか?どちらもLuceneベースの検索エンジンです。Elasticsearchはより優れた分散設計とAPIを備えています。Solrはより多くのエンタープライズ機能を持っています。ほとんどの新しいプロジェクトはElasticsearchを選択します。

検索で特殊文字を処理するにはどうすればよいですか?特殊文字 `()[]{}:^\"\\+-!~*?|` をバックスラッシュでエスケープします。または、より寛容な `simple_query_string` を使用します。

シャードとは何ですか?シャードはインデックスの一部です。各シャードはLuceneインデックスです。プライマリシャードは書き込み用、レプリカシャードは読み取りスケーリングと耐障害性のためのコピーです。

いくつのシャードを作成すべきですか?目安として、シャードあたり20〜50GBです。1つのプライマリシャードから始め、レプリカを追加します。プライマリシャードは必要な場合にのみ増やします(減らすことはできません)。

インデックス作成後にマッピングを変更できますか?部分的には可能です。新しいフィールドは自由に追加できます。既存のフィールドタイプを変更するには、データを再インデックス化します。一貫したマッピングを管理するには、インデックステンプレートを使用します。

_routingパラメーターとは何ですか?フィールド値に基づいてドキュメントを特定のシャードにルーティングします。デフォルトは `_id` です。クエリが常に特定のフィールド(user_idなど)でフィルタリングする場合、パフォーマンス向上のためにルーティングを使用します。

時系列データはどのように処理しますか?日付ベースのインデックス(例: `logs-2026.03.24`)を使用します。これにより、古いデータをインデックスを削除することで削除でき、検索対象のインデックスを減らすことでクエリパフォーマンスが向上します。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる