検索のトラブルシューティング
データをクエリすると、Elasticsearchはエラー、検索結果なし、または予期しない順序で結果を返すことがあります。このガイドでは、検索のトラブルシューティング方法について説明します。
データストリーム、インデックス、またはエイリアスが存在することを確認する
Elasticsearchは、クエリしようとしているデータストリーム、インデックス、またはエイリアスが存在しない場合にindex_not_found_exception
を返します。これは、名前を誤って入力した場合や、データが異なるデータストリームまたはインデックスにインデックスされた場合に発生する可能性があります。
exists APIを使用して、データストリーム、インデックス、またはエイリアスが存在するかどうかを確認します:
Python
resp = client.indices.exists(
index="my-data-stream",
)
print(resp)
Ruby
response = client.indices.exists(
index: 'my-data-stream'
)
puts response
Js
const response = await client.indices.exists({
index: "my-data-stream",
});
console.log(response);
コンソール
HEAD my-data-stream
data stream stats APIを使用して、すべてのデータストリームをリストします:
Python
resp = client.indices.data_streams_stats(
human=True,
)
print(resp)
Ruby
response = client.indices.data_streams_stats(
human: true
)
puts response
Js
const response = await client.indices.dataStreamsStats({
human: "true",
});
console.log(response);
コンソール
GET /_data_stream/_stats?human=true
get index APIを使用して、すべてのインデックスとそのエイリアスをリストします:
Python
resp = client.indices.get(
index="_all",
filter_path="*.aliases",
)
print(resp)
Ruby
response = client.indices.get(
index: '_all',
filter_path: '*.aliases'
)
puts response
Js
const response = await client.indices.get({
index: "_all",
filter_path: "*.aliases",
});
console.log(response);
コンソール
GET _all?filter_path=*.aliases
エラーの代わりに、クエリしているインデックスの一部が利用できない場合、部分的な検索結果を取得することができます。ignore_unavailable
をtrue
に設定します:
Python
resp = client.search(
index="my-alias",
ignore_unavailable=True,
)
print(resp)
Ruby
response = client.search(
index: 'my-alias',
ignore_unavailable: true
)
puts response
Js
const response = await client.search({
index: "my-alias",
ignore_unavailable: "true",
});
console.log(response);
コンソール
GET /my-alias/_search?ignore_unavailable=true
データストリームまたはインデックスにデータが含まれていることを確認する
検索リクエストがヒットを返さない場合、データストリームまたはインデックスにデータが含まれていない可能性があります。これは、データ取り込みの問題がある場合に発生する可能性があります。たとえば、データが別の名前のデータストリームまたはインデックスにインデックスされている可能性があります。
count APIを使用して、データストリームまたはインデックス内のドキュメント数を取得します。レスポンスのcount
が0でないことを確認します。
Python
resp = client.count(
index="my-index-000001",
)
print(resp)
Ruby
response = client.count(
index: 'my-index-000001'
)
puts response
Js
const response = await client.count({
index: "my-index-000001",
});
console.log(response);
コンソール
GET /my-index-000001/_count
Kibanaで検索結果が得られない場合、正しいデータビューと有効な時間範囲を選択していることを確認してください。また、データビューが正しい時間フィールドで構成されていることを確認してください。
フィールドが存在し、その機能を確認する
存在しないフィールドをクエリすると、結果は返されません。field capabilities APIを使用して、フィールドが存在するかどうかを確認します:
Python
resp = client.field_caps(
index="my-index-000001",
fields="my-field",
)
print(resp)
Ruby
response = client.field_caps(
index: 'my-index-000001',
fields: 'my-field'
)
puts response
Js
const response = await client.fieldCaps({
index: "my-index-000001",
fields: "my-field",
});
console.log(response);
コンソール
GET /my-index-000001/_field_caps?fields=my-field
フィールドが存在しない場合、データ取り込みプロセスを確認してください。フィールドには異なる名前が付けられている可能性があります。
フィールドが存在する場合、リクエストはフィールドのタイプと、検索可能かつ集約可能かどうかを返します。
コンソール-レスポンス
{
"indices": [
"my-index-000001"
],
"fields": {
"my-field": {
"keyword": {
"type": "keyword",
"metadata_field": false,
"searchable": true,
"aggregatable": true
}
}
}
}
このインデックスのフィールドはkeyword 型です。 |
|
このインデックスのフィールドは検索可能です。 | |
このインデックスのフィールドは集約可能です。 |
フィールドのマッピングを確認する
フィールドの機能は、そのマッピングによって決まります。マッピングを取得するには、get mapping APIを使用します:
Python
resp = client.indices.get_mapping(
index="my-index-000001",
)
print(resp)
Ruby
response = client.indices.get_mapping(
index: 'my-index-000001'
)
puts response
Js
const response = await client.indices.getMapping({
index: "my-index-000001",
});
console.log(response);
コンソール
GET /my-index-000001/_mappings
text
フィールドをクエリする場合、設定されている可能性のあるアナライザーに注意してください。analyze APIを使用して、フィールドのアナライザーが値やクエリ用語をどのように処理するかを確認します:
Python
resp = client.indices.analyze(
index="my-index-000001",
field="my-field",
text="this is a test",
)
print(resp)
Ruby
response = client.indices.analyze(
index: 'my-index-000001',
body: {
field: 'my-field',
text: 'this is a test'
}
)
puts response
Js
const response = await client.indices.analyze({
index: "my-index-000001",
field: "my-field",
text: "this is a test",
});
console.log(response);
コンソール
GET /my-index-000001/_analyze
{
"field" : "my-field",
"text" : "this is a test"
}
既存のフィールドのマッピングを変更するには、フィールドのマッピングを変更するを参照してください。
フィールドの値を確認する
exists
クエリを使用して、フィールドに値を返すドキュメントがあるかどうかを確認します。レスポンスのcount
が0でないことを確認します。
Python
resp = client.count(
index="my-index-000001",
query={
"exists": {
"field": "my-field"
}
},
)
print(resp)
Ruby
response = client.count(
index: 'my-index-000001',
body: {
query: {
exists: {
field: 'my-field'
}
}
}
)
puts response
Js
const response = await client.count({
index: "my-index-000001",
query: {
exists: {
field: "my-field",
},
},
});
console.log(response);
コンソール
GET /my-index-000001/_count
{
"query": {
"exists": {
"field": "my-field"
}
}
}
フィールドが集約可能な場合、集約を使用してフィールドの値を確認できます。keyword
フィールドの場合、terms aggregationを使用してフィールドの最も一般的な値を取得できます:
Python
resp = client.search(
index="my-index-000001",
filter_path="aggregations",
size=0,
aggs={
"top_values": {
"terms": {
"field": "my-field",
"size": 10
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'my-index-000001',
filter_path: 'aggregations',
body: {
size: 0,
aggregations: {
top_values: {
terms: {
field: 'my-field',
size: 10
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "my-index-000001",
filter_path: "aggregations",
size: 0,
aggs: {
top_values: {
terms: {
field: "my-field",
size: 10,
},
},
},
});
console.log(response);
コンソール
GET /my-index-000001/_search?filter_path=aggregations
{
"size": 0,
"aggs": {
"top_values": {
"terms": {
"field": "my-field",
"size": 10
}
}
}
}
数値フィールドの場合、stats aggregationを使用してフィールドの値の分布を把握できます:
Python
resp = client.search(
index="my-index-000001",
filter_path="aggregations",
aggs={
"my-num-field-stats": {
"stats": {
"field": "my-num-field"
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'my-index-000001',
filter_path: 'aggregations',
body: {
aggregations: {
"my-num-field-stats": {
stats: {
field: 'my-num-field'
}
}
}
}
)
puts response
Js
const response = await client.search({
index: "my-index-000001",
filter_path: "aggregations",
aggs: {
"my-num-field-stats": {
stats: {
field: "my-num-field",
},
},
},
});
console.log(response);
コンソール
GET my-index-000001/_search?filter_path=aggregations
{
"aggs": {
"my-num-field-stats": {
"stats": {
"field": "my-num-field"
}
}
}
}
フィールドが値を返さない場合、データ取り込みプロセスを確認してください。フィールドには異なる名前が付けられている可能性があります。
最新の値を確認する
時系列データの場合、試みた時間範囲内にフィルタリングされていないデータが存在することを確認します。たとえば、@timestamp
フィールドの最新データをクエリしようとしている場合、次のコマンドを実行して、最大@timestamp
が試みた範囲内にあるかどうかを確認します:
Python
resp = client.search(
index="my-index-000001",
sort="@timestamp:desc",
size="1",
)
print(resp)
Ruby
response = client.search(
index: 'my-index-000001',
sort: '@timestamp:desc',
size: 1
)
puts response
Js
const response = await client.search({
index: "my-index-000001",
sort: "@timestamp:desc",
size: 1,
});
console.log(response);
コンソール
GET my-index-000001/_search?sort=@timestamp:desc&size=1
クエリを検証、説明、プロファイルする
クエリが予期しない結果を返す場合、Elasticsearchはその理由を調査するためのいくつかのツールを提供します。
validate APIを使用して、クエリを検証できます。rewrite
パラメータを使用して、Elasticsearchクエリが書き換えられるLuceneクエリを返します:
Python
resp = client.indices.validate_query(
index="my-index-000001",
rewrite=True,
query={
"match": {
"user.id": {
"query": "kimchy",
"fuzziness": "auto"
}
}
},
)
print(resp)
Ruby
response = client.indices.validate_query(
index: 'my-index-000001',
rewrite: true,
body: {
query: {
match: {
'user.id' => {
query: 'kimchy',
fuzziness: 'auto'
}
}
}
}
)
puts response
Js
const response = await client.indices.validateQuery({
index: "my-index-000001",
rewrite: "true",
query: {
match: {
"user.id": {
query: "kimchy",
fuzziness: "auto",
},
},
},
});
console.log(response);
コンソール
GET /my-index-000001/_validate/query?rewrite=true
{
"query": {
"match": {
"user.id": {
"query": "kimchy",
"fuzziness": "auto"
}
}
}
}
explain APIを使用して、特定のドキュメントがクエリに一致する理由または一致しない理由を確認します:
Python
resp = client.explain(
index="my-index-000001",
id="0",
query={
"match": {
"message": "elasticsearch"
}
},
)
print(resp)
Ruby
response = client.explain(
index: 'my-index-000001',
id: 0,
body: {
query: {
match: {
message: 'elasticsearch'
}
}
}
)
puts response
Js
const response = await client.explain({
index: "my-index-000001",
id: 0,
query: {
match: {
message: "elasticsearch",
},
},
});
console.log(response);
コンソール
GET /my-index-000001/_explain/0
{
"query" : {
"match" : { "message" : "elasticsearch" }
}
}
profile APIは、検索リクエストに関する詳細なタイミング情報を提供します。結果の視覚的表現には、KibanaのSearch Profilerを使用します。
Kibanaでクエリのトラブルシューティングを行うには、ツールバーのInspectを選択します。次に、Requestを選択します。これで、KibanaがElasticsearchに送信したクエリをコピーして、コンソールでさらに分析できます。
インデックス設定を確認する
Index settingsは、検索結果に影響を与える可能性があります。たとえば、クエリが明示的なフィールドを指定しない場合にクエリされるフィールドを決定するindex.query.default_field
設定があります。get index settings APIを使用して、インデックスの設定を取得します:
Python
resp = client.indices.get_settings(
index="my-index-000001",
)
print(resp)
Ruby
response = client.indices.get_settings(
index: 'my-index-000001'
)
puts response
Js
const response = await client.indices.getSettings({
index: "my-index-000001",
});
console.log(response);
コンソール
GET /my-index-000001/_settings
動的インデックス設定は、update index settings APIを使用して更新できます。データストリームの動的インデックス設定を変更するには、データストリームによって使用されるインデックステンプレートを変更する必要があります。
静的設定の場合、正しい設定で新しいインデックスを作成する必要があります。次に、そのインデックスにデータを再インデックスできます。データストリームの場合は、データストリームの静的インデックス設定を変更するを参照してください。
遅いクエリを見つける
Slow logsは、遅いパフォーマンスの検索リクエストを特定するのに役立ちます。その上で、audit loggingを有効にすると、クエリのソースを特定するのに役立ちます。elasticsearch.yml
設定ファイルに次の設定を追加して、クエリをトレースします。結果のログは冗長であるため、トラブルシューティングを行っていないときはこれらの設定を無効にしてください。
Yaml
xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.include: _all
xpack.security.audit.logfile.events.emit_request_body: true
Advanced tuning: finding and fixing slow Elasticsearch queriesを参照して、詳細情報を確認してください。