排查搜索问题
编辑排查搜索问题
编辑当您查询数据时,Elasticsearch 可能会返回错误、没有搜索结果或结果顺序不符合预期。本指南描述了如何排查搜索问题。
确保数据流、索引或别名存在
编辑当您尝试查询的数据流、索引或别名不存在时,Elasticsearch 会返回 index_not_found_exception
。当您拼写错误名称或数据已被索引到不同的数据流或索引时,可能会发生这种情况。
使用 exists API 来检查数据流、索引或别名是否存在
resp = client.indices.exists( index="my-data-stream", ) print(resp)
response = client.indices.exists( index: 'my-data-stream' ) puts response
const response = await client.indices.exists({ index: "my-data-stream", }); console.log(response);
HEAD my-data-stream
使用 数据流统计 API 列出所有数据流
resp = client.indices.data_streams_stats( human=True, ) print(resp)
response = client.indices.data_streams_stats( human: true ) puts response
const response = await client.indices.dataStreamsStats({ human: "true", }); console.log(response);
GET /_data_stream/_stats?human=true
使用 获取索引 API 列出所有索引及其别名
resp = client.indices.get( index="_all", filter_path="*.aliases", ) print(resp)
response = client.indices.get( index: '_all', filter_path: '*.aliases' ) puts response
const response = await client.indices.get({ index: "_all", filter_path: "*.aliases", }); console.log(response);
GET _all?filter_path=*.aliases
如果正在查询的某些索引不可用,则可能不会返回错误,而是检索到部分搜索结果。将 ignore_unavailable
设置为 true
resp = client.search( index="my-alias", ignore_unavailable=True, ) print(resp)
response = client.search( index: 'my-alias', ignore_unavailable: true ) puts response
const response = await client.search({ index: "my-alias", ignore_unavailable: "true", }); console.log(response);
GET /my-alias/_search?ignore_unavailable=true
确保数据流或索引包含数据
编辑当搜索请求未返回任何匹配项时,数据流或索引可能不包含数据。当数据摄取出现问题时,可能会发生这种情况。例如,数据可能已被索引到另一个名称的数据流或索引中。
使用 计数 API 来检索数据流或索引中的文档数。检查响应中的 count
是否不为 0。
resp = client.count( index="my-index-000001", ) print(resp)
response = client.count( index: 'my-index-000001' ) puts response
const response = await client.count({ index: "my-index-000001", }); console.log(response);
GET /my-index-000001/_count
当在 Kibana 中没有获得任何搜索结果时,请检查您是否选择了正确的数据视图和有效的时间范围。此外,请确保已使用正确的时间字段配置了数据视图。
检查字段是否存在及其功能
编辑查询不存在的字段将不会返回任何结果。使用 字段功能 API 来检查字段是否存在
resp = client.field_caps( index="my-index-000001", fields="my-field", ) print(resp)
response = client.field_caps( index: 'my-index-000001', fields: 'my-field' ) puts response
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 } } } }
检查字段的映射
编辑字段的功能由其映射决定。要检索映射,请使用 获取映射 API
resp = client.indices.get_mapping( index="my-index-000001", ) print(resp)
response = client.indices.get_mapping( index: 'my-index-000001' ) puts response
const response = await client.indices.getMapping({ index: "my-index-000001", }); console.log(response);
GET /my-index-000001/_mappings
如果您查询 text
字段,请注意可能已配置的分析器。您可以使用 分析 API 来检查字段的分析器如何处理值和查询词
resp = client.indices.analyze( index="my-index-000001", field="my-field", text="this is a test", ) print(resp)
response = client.indices.analyze( index: 'my-index-000001', body: { field: 'my-field', text: 'this is a test' } ) puts response
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。
resp = client.count( index="my-index-000001", query={ "exists": { "field": "my-field" } }, ) print(resp)
response = client.count( index: 'my-index-000001', body: { query: { exists: { field: 'my-field' } } } ) puts response
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
字段,您可以使用 词项聚合 来检索字段的最常见值
resp = client.search( index="my-index-000001", filter_path="aggregations", size=0, aggs={ "top_values": { "terms": { "field": "my-field", "size": 10 } } }, ) print(resp)
response = client.search( index: 'my-index-000001', filter_path: 'aggregations', body: { size: 0, aggregations: { top_values: { terms: { field: 'my-field', size: 10 } } } } ) puts response
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 } } } }
对于数值字段,您可以使用 统计聚合 来了解字段的值分布
resp = client.search( index="my-index-000001", filter_path="aggregations", aggs={ "my-num-field-stats": { "stats": { "field": "my-num-field" } } }, ) print(resp)
response = client.search( index: 'my-index-000001', filter_path: 'aggregations', body: { aggregations: { "my-num-field-stats": { stats: { field: 'my-num-field' } } } } ) puts response
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
是否在尝试的范围内
resp = client.search( index="my-index-000001", sort="@timestamp:desc", size="1", ) print(resp)
response = client.search( index: 'my-index-000001', sort: '@timestamp:desc', size: 1 ) puts response
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 提供了几种工具来调查原因。
验证 API 使您能够验证查询。使用 rewrite
参数来返回 Elasticsearch 查询被重写成的 Lucene 查询
resp = client.indices.validate_query( index="my-index-000001", rewrite=True, query={ "match": { "user.id": { "query": "kimchy", "fuzziness": "auto" } } }, ) print(resp)
response = client.indices.validate_query( index: 'my-index-000001', rewrite: true, body: { query: { match: { 'user.id' => { query: 'kimchy', fuzziness: 'auto' } } } } ) puts response
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" } } } }
使用 解释 API 来查明为什么特定的文档与查询匹配或不匹配
resp = client.explain( index="my-index-000001", id="0", query={ "match": { "message": "elasticsearch" } }, ) print(resp)
response = client.explain( index: 'my-index-000001', id: 0, body: { query: { match: { message: 'elasticsearch' } } } ) puts response
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" } } }
分析 API 提供了有关搜索请求的详细计时信息。要查看结果的可视化表示,请使用 Kibana 中的 搜索分析器。
要在 Kibana 中排查查询问题,请在工具栏中选择 检查。接下来,选择 请求。现在,您可以复制 Kibana 发送到 Elasticsearch 的查询,以便在控制台中进行进一步分析。
检查索引设置
编辑索引设置可能会影响搜索结果。例如,index.query.default_field
设置,它确定当查询未指定显式字段时查询的字段。使用 获取索引设置 API 来检索索引的设置
resp = client.indices.get_settings( index="my-index-000001", ) print(resp)
response = client.indices.get_settings( index: 'my-index-000001' ) puts response
const response = await client.indices.getSettings({ index: "my-index-000001", }); console.log(response);
GET /my-index-000001/_settings
您可以使用 更新索引设置 API 来更新动态索引设置。更改数据流的动态索引设置需要更改数据流使用的索引模板。
对于静态设置,您需要使用正确的设置创建一个新索引。接下来,您可以将数据重新索引到该索引中。对于数据流,请参阅 更改数据流的静态索引设置。
查找慢查询
编辑慢日志可以帮助查明性能较慢的搜索请求。在顶部启用 审计日志记录 可以帮助确定查询来源。将以下设置添加到 elasticsearch.yml
配置文件以跟踪查询。生成的日志记录非常详细,因此在不进行故障排除时请禁用这些设置。
xpack.security.audit.enabled: true xpack.security.audit.logfile.events.include: _all xpack.security.audit.logfile.events.emit_request_body: true
有关更多信息,请参阅 高级调整:查找和修复慢速 Elasticsearch 查询。