当前位置:首页 > ELK > 正文内容

elasticsearch中的常见问题和优化策略

phpmianshi2年前 (2019-08-02)ELK114

常见优化策略:

filter过滤器查询优化

结果分数是Elasticsearch的关键。 通常,当您使用搜索引擎时,您需要最准确的结果。 例如,如果您正在搜索“苹果”,您不希望结果包括“苹果手机”。

Elasticsearch根据您提供的参数对查询结果进行评分。

虽然查询相关性不是本篇文章的重点,但重要的是在此提及,因为如果您有快速搜索需求但结果不是您要查找的结果,则整个搜索都是浪费时间。 那么,你如何加快搜索速度?

1 查询时,使用query-bool-filter组合取代普通query

提高搜索性能的一种方法是使用过滤器。 过滤后的查询可能是您最需要的。

首先过滤是很重要的,因为搜索中的过滤器不会影响文档分数的结果,因此您在资源方面使用很少的资源来将搜索结果范围缩小到很小。

使用过滤查询,结合使用布尔匹配,您可以在评分之前搜索包含X的所有文档,或者不包含Y的所有文档。此外,可以filter是可以被缓存的。


2 避免使用script查询

避免使用脚本查询来计算匹配。 推荐:建立索引时存储计算字段。

例如,我们有一个包含大量用户信息的索引,我们需要查询编号以“1234”开头的所有用户。 您可能希望运行类似“source”的脚本查询: doc ['num'].value.startsWith('1234') 此查询非常耗费资源并且会降低整个系统的速度。  合理的建议:考虑在索引时添加名为“num_prefix”的字段。 然后我们可以查询 “name_prefix”:“1234”。

3 避免使用wildcard查询

主要原因:wildcard类似mysql中的like,和分词完全没有了关系。

出现错误:用户输入的字符串长度没有做限制,导致首尾通配符中间可能是很长的一个字符串。 后果就是对应的wildcard Query执行非常慢,非常消耗CPU。

根本原因:为了加速通配符和正则表达式的匹配速度,Lucene4.0开始会将输入的字符串模式构建成一个DFA (Deterministic Finite Automaton),带有通配符的pattern构造出来的DFA可能会很复杂,开销很大。

可能的优化方案:

  1. wildcard query应杜绝使用通配符打头,实在不得已要这么做,就一定需要限制用户输入的字符串长度。

  2. 最好换一种实现方式,通过在index time做文章,选用合适的分词器,比如nGram tokenizer预处理数据,然后使用更廉价的term query来实现同等的模糊搜索功能。

  3. 对于部分输入即提示的应用场景,可以考虑优先使用completion suggester, phrase/term/suggeter一类性能更好,模糊程度略差的方式查询,待suggester没有匹配结果的时候,再fall back到更模糊但性能较差的wildcard, regex, fuzzy一类的查询。

详尽原理参考:https://elasticsearch.cn/article/171

4 合理使用keyword类型

ES5.x里对数值型字段做TermQuery可能会很慢。

在ES5.x+里,一定要注意数值类型是否需要做范围查询,看似数值,但其实只用于Term或者Terms这类精确匹配的,应该定义为keyword类型。

典型的例子就是索引web日志时常见的HTTP Status code。

详尽原理参考:https://elasticsearch.cn/article/446

5 控制字段的返回

一是:数据建模规划的时候,在Mapping节点对于仅存储、是否构建倒排索引通过enabled、index参数进行优化。

二是:_source控制返回,不必要的字段不需要返回,举例:采集的原文章详情内容页,根据需要决定是否返回。

6 空值的处理

如果同步的内容有可能有空值尽量设置一个默认值

6.1 比如:state状态为空为正常状态,则可以设置一个默认none,查询正常状态就可以term=none  查询不为空可以把所有可能的情况都列出来用terms

SELECT (CASE state WHEN '' THEN 'none' ELSE state END) as es_state from table

6.2 当然最好还是用 keyword分析器来查询, 比如 filed.keyword="" 这样也是能正常查询出来的

常见问题和解决方案

1.text类型需要排序

报错如下:

Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index

场景:

定义了is_hot 是否热门,为了让它支持精确查询,定义成了text类型,但是还需要先根据是否热门排序,再根据热度排序


问题原因:

根据官方文档显示,出现该错误是因为5.x之后,Elasticsearch对排序、聚合所依据的字段用单独的数据结构(fielddata)缓存到内存里了,但是在text字段上默认是禁用的,如果有需要单独开启,这样做的目的是为了节省内存空间。

官方文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html

开启方法:

curl -XPUT 'http://localhost:9200/my_index/_mapping' -d '
{
  "properties": {
        "is_hot": {
            "type": "text",
            "fielddata": true
        }
    }
}'


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

elasticsearch中最重要的查询过滤语句

term 过滤term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型){ "term": { "age&q...

logstash过滤器--mutate

概念filters/mutate 插件是 Logstash 另一个重要插件。它提供了丰富的基础类型数据处理能力。包括类型转换,字符串处理和字段处理等。Plugin version: v3.5.0执行顺...

elasticsearch中mapping全解实战

Mapping简介#mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用mapping 来定义以下内容:哪些字段需要被定义为全文检索类型哪些字段包含number、dat...

logstash实现reindex

概念Elasticsearch 本身不提供对索引的 rename,mapping 的 alter 等操作。所以,如果有需要对全索引数据进行导出,或者修改某个已有字段的 mapping 设置等情况下,我...

elasticsearch中query和filter区别

区别在进行query的时候,除了完成匹配的过程,我们实际上在问“这个结果到底有多匹配我们的搜索关键词”。在所有的返回结果的后面都会有一个_score字段表示这个结果的匹配程度,也就是相关性。相关性越高...

logstash-keystore保存Elasticsearch或其他密码

背景在配置Logstash时,你可能需要指定敏感设置或配置,比如密码,与依赖文件系统权限来保护这些值不同,你可以使用Logstash keystore来安全地存储用于配置设置的secret值。在向ke...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。