故障排除搜索

edit

当您查询数据时,Elasticsearch 可能会返回错误、无搜索结果或结果顺序异常。本指南描述了如何排查搜索问题。

确保数据流、索引或别名存在

edit

当您尝试查询的数据流、索引或别名不存在时,Elasticsearch 会返回一个 index_not_found_exception。这可能发生在您拼写错误时,或者当数据已被索引到不同的数据流或索引时。

使用exists API来检查数据流、索引或别名是否存在:

HEAD my-data-stream

使用 数据流统计 API 列出所有数据流:

GET /_data_stream/_stats?human=true

使用获取索引API来列出所有索引及其别名:

GET _all?filter_path=*.aliases

如果某些索引不可用,可以检索部分搜索结果,而不是返回错误。将 ignore_unavailable 设置为 true

GET /my-alias/_search?ignore_unavailable=true

确保数据流或索引包含数据

edit

当搜索请求没有返回任何结果时,数据流或索引可能不包含任何数据。这可能发生在存在数据摄取问题时。例如,数据可能已被索引到具有不同名称的数据流或索引中。

使用count API来检索数据流或索引中的文档数量。检查响应中的count是否不为0。

GET /my-index-000001/_count

当在Kibana中未获得搜索结果时,请检查您是否选择了正确的数据视图和有效的时间范围。同时,确保数据视图已配置了正确的时间字段。

检查字段是否存在及其功能

edit

查询一个不存在的字段将不会返回任何结果。使用字段能力 API来检查一个字段是否存在:

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

该字段在此索引中是可搜索的。

该字段在此索引中是可聚合的。

检查字段的映射

edit

字段的功能由其映射决定。要检索映射,请使用获取映射API

GET /my-index-000001/_mappings

如果你查询一个text字段,请注意可能已配置的分析器。你可以使用analyze API来检查字段的分析器如何处理值和查询词:

GET /my-index-000001/_analyze
{
  "field" : "my-field",
  "text" : "this is a test"
}

要更改现有字段的映射,请参阅 更改字段的映射

检查字段的值

edit

使用exists查询来检查是否存在返回字段值的文档。检查响应中的count是否不为0。

GET /my-index-000001/_count
{
  "query": {
    "exists": {
      "field": "my-field"
    }
  }
}

如果该字段是可聚合的,您可以使用聚合 来检查该字段的值。对于keyword字段,您可以使用 词条聚合来检索 该字段的最常见值:

GET /my-index-000001/_search?filter_path=aggregations
{
  "size": 0,
  "aggs": {
    "top_values": {
      "terms": {
        "field": "my-field",
        "size": 10
      }
    }
  }
}

对于数值字段,您可以使用统计聚合来了解字段的值分布:

GET my-index-000001/_search?filter_path=aggregations
{
  "aggs": {
    "my-num-field-stats": {
      "stats": {
        "field": "my-num-field"
      }
    }
  }
}

如果该字段没有返回任何值,请检查数据摄取过程。该字段可能具有不同的名称。

检查最新值

edit

对于时间序列数据,确认在尝试的时间范围内存在未过滤的数据。例如,如果您正在尝试查询@timestamp字段的最新数据,请运行以下命令以查看最大@timestamp是否在尝试的范围内:

GET my-index-000001/_search?sort=@timestamp:desc&size=1

验证、解释和分析查询

edit

当查询返回意外结果时,Elasticsearch 提供了几种工具来调查原因。

The validate API 使您能够验证查询。使用 rewrite 参数来返回 Elasticsearch 查询被重写成的 Lucene 查询:

GET /my-index-000001/_validate/query?rewrite=true
{
  "query": {
    "match": {
      "user.id": {
        "query": "kimchy",
        "fuzziness": "auto"
      }
    }
  }
}

使用 explain API 来找出为什么某个特定文档匹配或不匹配查询:

GET /my-index-000001/_explain/0
{
  "query" : {
    "match" : { "message" : "elasticsearch" }
  }
}

The profile API 提供了关于搜索请求的详细时间信息。为了直观地表示结果,请在 Kibana 中使用 Search Profiler

要在 Kibana 中排查查询问题,请在工具栏中选择 检查。接下来,选择 请求。现在,您可以复制 Kibana 发送到 Elasticsearch 的查询,以便在控制台中进行进一步分析。

检查索引设置

edit

索引设置可以影响搜索结果。例如,index.query.default_field设置,它决定了当查询没有指定明确字段时所查询的字段。使用获取索引设置 API来检索索引的设置:

GET /my-index-000001/_settings

您可以使用更新索引设置 API来更新动态索引设置。更改数据流的动态索引设置需要更改数据流使用的索引模板。

对于静态设置,您需要创建一个具有正确设置的新索引。 接下来,您可以将数据重新索引到该索引中。对于数据流,请参阅 更改数据流的静态索引设置

查找慢查询

edit

慢日志可以帮助定位执行缓慢的搜索请求。启用审计日志可以进一步帮助确定查询来源。将以下设置添加到elasticsearch.yml配置文件中以跟踪查询。生成的日志记录非常详细,因此在不需要故障排除时请禁用这些设置。

xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.include: _all
xpack.security.audit.logfile.events.emit_request_body: true

请参阅 高级调优:查找和修复慢速 Elasticsearch 查询以获取更多信息。