Elasticsearch とは、複数のファイルから特定の文字列を分散検索するソフトウェアです。
具体的には google 検索や、github のソースコード検索のような全文検索 (後述) が行えます。
なお、Elasticsearch に関連する記事は以下です。
- Elasticsearch とは (概要/できること/検索方法)
- マッピング管理とテンプレート
- Analyzer の設定 (日本語検索、トークナイズ)
- 集計・分類 (Aggregations)
- Dynamic index settings の変更
- データ構造
全文検索とは
全文検索には、主に以下の2つの手法があります。
grep 型
UNIX の grep コマンドが、こちらに当たります。
索引 (インデックス) 型

Elasticsearch の全文検索が、こちらに当たります。
インデックス型では、検索する単語を1行だけスキャンすれば良いので、高速に検索できます。
※ grep 型ではドキュメントをフルスキャンする必要があります
インデックス型の全文検索を利用した例は以下のとおりです。
全文検索の例 | 説明 |
---|---|
Elasticsearch の検索 | 複数のファイル (ドキュメント) から一致する文字列を検索 |
Google 検索 | 複数のファイル (Webページ) から一致する文字列を検索 |
GitHub のソースコード検索 | 複数のファイル (ソースコード) から一致する文字列を検索 |
Elasticsearch 用途/事例/できる事
Elasticsearch の主な利用用途は以下の2つです。
ドキュメント検索
企業におけるドキュメント検索の利用例は以下のとおりです。
■ZOZOTOWN: 商品検索
■GitHub: ソースコード検索

■日経新聞: 記事の検索、アクセスログの解析

異常検知
企業における異常検知の利用例は以下のとおりです。
■RICOH: セキュリティインシデントの検知

■Netflix: セキュリティログの監視
Elastic Stack (ELK Stack) とは
Elastic Stack (ELK Stack) とは、以下の4つのソフトウェアのことです。
ソフトウェア | 説明 |
---|---|
Elasticsearch | ファイル (ドキュメント) を保存・検索 |
Kibana | Elasticsearch 内のドキュメントを可視化する BI ツール |
Logstash | Elasticsearch に送信するデータの形式を変換 |
Beats | サーバーから Elasticsearch や Logstash にデータを転送 |
Kibana については、公式で紹介されている以下の GIF 画像を見るのがわかりやすいです。

Logstash や Beats の代わりに、Fluentd でデータを収集する構成も一般的です。
こちらの構成は EFK (Elasticsearch, Fluentd, Kibana) と呼ばれます。
Elasticsearch のアーキテクチャ
Elasticsearch では、データを以下のように持ちます。

インデックスは、以下のように配置します。

ノードには、主に次の4種類の属性が存在します。
ノードの種類 | 役割 |
---|---|
Master ノード | クラスターのメタデータなどを管理するノード ・Master ノードはクラスターに1台のみ ・それ以外のノードは Master-eligible ノードと呼ぶ ・Master-eligible ノードが昇格すると Master ノードになる |
Data ノード | データを格納・リクエストの処理(検索や集計など)するノード |
Ingest ノード | データの変換や加工し、Data ノードに格納するノード ・Logstash と同じ役割 |
Coordinating ノード | リクエストを適切なシャードにルーティングするノード ・Data ノードでもリクエストはルーティング可能 ・Data ノードにルーティング処理の負荷を掛けたくない場合に設定 |
Elasticsearch では、シャード単位で並列処理が可能です。
シャードには、以下の2種類が存在します。
用語 | 説明 |
---|---|
プライマリーシャード | 書き込み処理を行うシャード |
レプリカシャード | プライマリーシャードのコピー (レプリケーション) 検索処理の負荷分散や、データのバックアップとして利用 |
なお、インデックス、シャード、ドキュメントの関連は、以下のとおりです。
シャード (Elasticsearch shard) は、複数のドキュメントを持ちます。

Elasticsearch のインストール
ここからは、Docker を使った Elasticsearch のインストール方法を紹介します。
Docker を使わないインストール方法はこちら
ここでは Amazon Linux 2 でインストールする方法を紹介します。
その他の OS については以下のドキュメントをご覧ください。
■Elasticsearch のインストール
Kibana のインストール
Java のインストール
Elasticsearch を実行するには Java 8 が必要なので、まずは Java 8 をインストールします。
openjdk version "1.8.0_252" OpenJDK Runtime Environment (build 1.8.0_252-b09) OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)
openjdk version "1.8****" 以上であれば OK です。
Elasticsearch のインストール
次に Elasticsearch をインストールします。
[elasticsearch] name=Elasticsearch repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=0 autorefresh=1 type=rpm-md
{ "name" : "***", "cluster_name" : "elasticsearch", "cluster_uuid" : "***", "version" : { "number" : "7.10.0", "build_flavor" : "default", "build_type" : "rpm", "build_hash" : "***", "build_date" : "2020-11-09T21:30:33.964949Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
Kibana のインストール
Kibana をインストールします。
[kibana-7.x] name=Kibana repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md
ブラウザから Kibana(localhost:5601) にアクセスします。
以下のページが表示されれば成功です。(この記事は Kibana バージョン 7.10.0です)

アクセスできない場合
なお、docker については以下の記事をご覧ください。
docker コンテナを作成
version: '3' services: elasticsearch: image: elasticsearch:7.12.1 container_name: elasticsearch environment: - discovery.type=single-node ports: - 9200:9200 kibana: image: kibana:7.12.1 ports: - "5601:5601" environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
これでシングルノードの Elasticsearch コンテナが立ち上がります。
Elasticsearch にアクセス
{ "name" : "123456789abc", "cluster_name" : "docker-cluster", "cluster_uuid" : "1234567890abcdefghijkl", "version" : { "number" : "7.12.1", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "1234567891456789123456789", "build_date" : "2021-04-20T20:56:39.040728659Z", "build_snapshot" : false, "lucene_version" : "8.8.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
起動に成功している場合は、上記のような結果が返ってきます。
※ 「curl: (56) Recv failure: Connection reset by peer」が返ってくる場合は初期化処理が完了するまでお待ちください。
Kibana にアクセス
Kibana コンテナにアクセスするために、ブラウザで http://localhost:5601 を開きます。

Elasticsearch の使い方
Elasticsearch は以下のようなツールを使い、REST API で操作します。
なお、Kibana の Dev Tools は以下の手順で開けます。

今回は現時点で最新のメジャーバージョンである Elasticsearch 7.x の使い方を説明します。(Elsticsearch はメジャーバージョンが変化すると、後方互換性がなくなります。)
CRUD 操作 + Bulk API
Elasticsearch の REST API では、ドキュメントに対して以下のような CRUD 操作が可能です。
REST API | 説明 | 対応する CRUD |
---|---|---|
Index API | インデックスにドキュメントを追加 | Create |
Get API | インデックスのドキュメントを取得 | Read |
Update API | インデックスのドキュメントを更新 | Update |
Delete API | インデックスのドキュメントを削除 | Delete |
PUT /<インデックス名>/_doc/<ドキュメント ID>
で指定したインデックスにドキュメントを追加できます。
PUT /test/_doc/1 { "date":"2020/11/01 09:00 JST", "Tweet":"ツイッターをはじめました。", "User ID":"hoge" }

右上の三角ボタンで実行します。
curl の場合
{ "date":"2020/11/01 09:00 JST", "Tweet":"ツイッターをはじめました。", "User ID":"hoge" }'
補足 データストリームへドキュメントを追加する場合
データストリームとは、複数のインデックスを1つにまとめたものです。
データストリームの詳細は以下のドキュメントに記載がございます。
データストリームにドキュメントを追加するためには、以下の REST API を利用します。
PUT /tweet/_create/1 { "date":"2020/11/01 09:00 JST", "Tweet":"ツイッターをはじめました。", "User ID":"hoge" }
{ (中略) "_source" : { "date" : "2020/11/01 09:00 JST", "Tweet" : "ツイッターをはじめました。", "User ID" : "hoge" } }
curl の場合
{ (中略) "_source" : { "date" : "2020/11/01 09:00 JST", "Tweet" : "ツイッターをはじめました。", "User ID" : "hoge" } }
一部のフィールドを更新
POST /test/_update/1 { "doc": { "Tweet":"フィールドを更新したよ。" } }
"_version" : 2
"_source" : {
"date" : "2020/11/01 09:00 JST",
"Tweet" : "フィールドを更新したよ。",
"User ID" : "hoge"
}
"Tweet" フィールドの値が更新され、_version が 2 に変化していることがわかります。
全てのフィールド (ドキュメント) を更新
POST /test/_doc/1 { "Tweet":"ドキュメントを置き換えたよ" }
"_version" : 3, "_source" : { "Tweet" : "ドキュメントを置き換えたよ" }
以下の3つが確認できます。
- Tweet フィールドが上書き
- date, User ID フィールドが消える
- _version が 3 に変化
curl の場合
{ "date":"2020/11/01 09:00 JST", "Tweet":"ドキュメントを更新したよ。", "User ID":"hoge" }'
{ (中略) "_version" : 2, "_source" : { "date" : "2020/11/01 09:00 JST", "Tweet" : "ドキュメントを更新したよ。", "User ID" : "hoge" }
"Tweet" フィールドの値が更新され、_version が2に変化していることがわかります。
POST <index>/_update/<_id> を使う場合
POST /test/_update/1 { "doc": { "Tweet":"ドキュメントを一部更新したよ。" } }
{ (中略) "_source" : { "date" : "2020/11/01 09:00 JST", "Tweet" : "ドキュメントを一部更新したよ。", "User ID" : "hoge" }
{ "_index" : "test", "_type" : "_doc", "_id" : "1", "found" : false }
found" が false となりました。("_source" のフィールドが削除されました。)
curl の場合
Bulk API で利用可能な操作は以下のとおりです。
Bulk API の操作 | 説明 |
---|---|
Create | インデックスが存在しない場合、ドキュメントを作成 |
Index | インデックスのドキュメントを全て更新 (置き換え) |
Update | インデックスのドキュメントを一部更新 |
Delete | インデックスのドキュメントを削除 |
POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
curl の場合
Bulk API で操作する内容を記載した json ファイルを作成します。
{ "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
ドキュメントの検索 (search API)
Elasticsearch では、search API を利用してインデックス内にあるドキュメントを検索します。
search API では、「4種類の検索条件 + ソート」で検索可能です。
それでは、今回のデモで使用するデータを用意します。
POST /_bulk { "index" : { "_index" : "demo_search", "_id" : "1" } } { "text" : "This is Elasticsearch test.", "num" : 1 } { "index" : { "_index" : "demo_search", "_id" : "2" } } { "text" : "Elasticsearch is God.", "num" : 2 } { "index" : { "_index" : "demo_search", "_id" : "3" } } { "text" : "This is a pen.", "num" : 3 }
条件無しで検索
まずは検索条件を指定せずに search API でドキュメントを検索してみます。
"hits" : [ { "_index" : "demo_search", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { "text" : "This is Elasticsearch test.", "num" : 1 } }, { "_index" : "demo_search", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "text" : "Elasticsearch is God.", "num" : 2 } }, { "_index" : "demo_search", "_type" : "_doc", "_id" : "3", "_score" : 1.0, "_source" : { "text" : "This is a pen.", "num" : 3 } } ]
作成した3つのドキュメントがすべて検索できています。
match クエリでは、「text」データ型のフィールドに対して全文検索を行います。
これは、「text」フィールドが単語ごとに転置インデックスを作成しているためです。
These fields are analyzed, that is they are passed through an analyzer to convert the string into a list of individual terms before being indexed.
https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html
フィールドのデータ型を指定する方法は、以下の記事で紹介しています。
match クエリで、 "Elasticsearch" と "god" の両方が含まれるドキュメントを全文検索します。
GET /demo_search/_search { "query":{ "match": { "text": { "query": "Elasticsearch god", "operator":"AND" } } } }
"hits" : [ (省略) "_source" : { "text" : "Elasticsearch is God."
match_phrase クエリについて
GET /demo_search/_search { "query":{ "match_phrase": { "text": "Elasticsearch test" } } }
"hits" : [ (省略) "_source" : { "text" : "This is Elasticsearch test." } }
GET /demo_search/_search
{
"query":{
"match_phrase": {
"text":{
"query": "test Elasticsearch"
}
}
}
}
"hits" : [ ]
Term クエリでは、データ型が「keyword」のフィールドに対して完全一致検索を行います。
(text 型は、単語ごとに転置インデックスを作成しているので、完全一致検索ができない)
Keyword fields are often used in sorting, aggregations, and term-level queries, such as
https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.htmlterm
.
GET /demo_search/_search
{
"query":{
"term": {
"text.keyword": "This is Elasticsearch test."
}
}
}
"_source" : {
"text" : "This is Elasticsearch test."
部分検索できない例
GET /demo_search/_search { "query":{ "term": { "text.keyword": "Elasticsearch" } } }
"hits" : [ ]
"Elasticsearch" は "This is Elasticsearch test." と異なるので、完全一致検索にヒットしないです。
Terms クエリ (複数形)
GET /demo_search/_search
{
"query":{
"terms": {
"text.keyword":["This is Elasticsearch test.","This is a pen."]
}
}
}
"_source" : { "text" : "This is Elasticsearch test." } (中略) "_source" : { "text" : "This is a pen." }
GET /demo_search/_search { "query":{ "range": { "num":{ "gte": "1", "lte": "2" } } } }
"hits" : [ { "_index" : "demo_search", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { "text" : "This is Elasticsearch test.", "num" : 1 } }, { "_index" : "demo_search", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "text" : "Elasticsearch is God.", "num" : 2 } }
num フィールドの値が1以上、2以下のドキュメントを検索できました。
bool クエリには、以下の4種類のクエリが存在します。
bool クエリの種類 | 説明 |
---|---|
must クエリ | AND 条件 |
should クエリ | OR 条件 |
must_not クエリ | NOT 条件 |
filter クエリ | フィルタリング |
GET /demo_search/_search { "query":{ "bool": { "must":[ {"match":{"text":"Elasticsearch"}}, {"range":{"num":{"lte":"1"}}} ] } } }
"_source" : { "text" : "This is Elasticsearch test.", "num" : 1 }
「text = "Elasticsearch" を含む」AND「num = 1以下」のドキュメントを検索できています。
GET /demo_search/_search { "query":{ "bool": { "should":[ {"match":{"text":"God"}}, {"range":{"num":{"gte":"2"}}} ] } } }
"hits" : [ { "_index" : "demo_search", "_type" : "_doc", "_id" : "2", "_score" : 2.0596457, "_source" : { "text" : "Elasticsearch is God.", "num" : 2 } }, { "_index" : "demo_search", "_type" : "_doc", "_id" : "3", "_score" : 1.0, "_source" : { "text" : "This is a pen.", "num" : 3
「text = "God" を含む」OR「num = 2以上」のドキュメントを検索できています。
なお、両方の条件を満たすドキュメントのほうが "_score" の値が高くなります。
GET /demo_search/_search { "query":{ "bool": { "must_not":[ {"match":{"text":"Elasticsearch"}}, {"range":{"num":{"lte":"1"}}} ] } } }
"hits" : [ { "_index" : "demo_search", "_type" : "_doc", "_id" : "3", "_score" : 0.0, "_source" : { "text" : "This is a pen.", "num" : 3 } }
「text = "Elasticsearch" を含まない」AND「num = 1以下でない」ドキュメントを検索できました。
つまり、"_score" が 0 のドキュメントです。
GET /demo_search/_search { "query":{ "bool": { "must": [ {"match":{"text":"Elasticsearch"}} ], "filter":[ {"range":{"num":{"lte":"1"}}} ] } } }
"_source" : { "text" : "This is Elasticsearch test.", "num" : 1 }
"text" = "Elasticsearch is God." は must 条件に一致しますが、"num" = 2 のため、検索結果から除外されています。
GET /demo_search/_search
{
"sort": [
{
"num": {
"order": "desc"
}
}
]
}
"_source" : { "text" : "This is a pen.", "num" : 3 }, "sort" : [ 3 ] (中略) "_source" : { "text" : "Elasticsearch is God.", "num" : 2 }, "sort" : [ 2 ] (中略) "_source" : { "text" : "This is Elasticsearch test.", "num" : 1 }, "sort" : [ 1 ]
num フィールドの値を用いて、降順 (desc) となっています。
関連情報
関連記事
- Elasticsearch とは (概要/できること/検索方法)
- マッピング管理とテンプレート
- Analyzer の設定 (日本語検索、トークナイズ)
- 集計・分類 (Aggregations)
- Dynamic index settings の変更
- データ構造
参考文献
公式ドキュメント