【手把手】ElasticSearch索引的批量操作及模糊智能搜索

导读:本篇文章讲解 【手把手】ElasticSearch索引的批量操作及模糊智能搜索,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

_mget 批量查询

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

这是一句最简单的批量查询的语句,使用ES官方提供的_mget进行批量查询。但是这个查询其实真的很糟糕,稍微复杂一点的需求就会包含大量重复的条件在里面。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

这个就相当于MySQL中的 select * from [table_name] where id in (2, 3, 4, 5);

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

通过“_source”: [“field”, “field”]指定需要的字段

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

也可以通过“_source”: {“include”:[]}“_source”: {“exclude”:[]}指定需要和不需要的字段

_bulk 批量增删改

数据的写入

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

要注意,_bulk的格式不像传统的那样那么多空格,而是必须采用这种规定的格式,写成传统的格式就会报错,一定要格式化成规定的格式才可以 

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

数据的删除

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

数据的修改

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

指定参数

filter_path=items.*.error

通过参数指定只看失败的信息

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

prefix 前缀搜索

以前缀开头的搜索,不计算相关度得分

  • 前缀搜索匹配的是term,而不是field。
  • 前缀搜索的性能很差
  • 前缀搜索没有缓存
  • 前缀搜索尽可能把前缀长度设置的更长

GET /<index>/_search
{
  “query”: {
    “prefix”: {
      “<field>”: {
        “value”: “<word_prefix>”
      }
    }
  }
}
index_prefixes: 默认   “min_chars” : 2,   “max_chars” : 5 

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

wildcard 通配符搜索

通配符运算符是匹配一个或多个字符的占位符。例如,*通配符运算符匹配零个或多个字符。您可以将通配符运算符与其他字符结合使用以创建通配符模式。

  • 通配符匹配的也是term,而不是field

GET <index>/_search
{
  “query”: {
    “wildcard”: {
      “<field>”: {
        “value”: “<word_with_wildcard>”
      }
    }
  }
}

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

regexp 正则搜索

regexp查询的性能可以根据提供的正则表达式而有所不同。为了提高性能,应避免使用通配符模式,如.或 .?+未经前缀或后缀

GET <index>/_search
{
  “query”: {
    “regexp”: {
      “<field>”: {
        “value”: “<regex>”,
        “flags”: “ALL”,
      }
    }
  }
}

  • ALL

    启用所有可选操作符。

  • COMPLEMENT

    启用~操作符。可以使用~对下面最短的模式进行否定。例如

    a~bc # matches ‘adc’ and ‘aec’ but not ‘abc’

  • INTERVAL

    启用<>操作符。可以使用<>匹配数值范围。例如

    foo<1-100> # matches ‘foo1’, ‘foo2’ … ‘foo99’, ‘foo100’

    foo<01-100> # matches ‘foo01’, ‘foo02’ … ‘foo99’, ‘foo100’

  • INTERSECTION

    启用&操作符,它充当AND操作符。如果左边和右边的模式都匹配,则匹配成功。例如:

    aaa.+&.+bbb # matches ‘aaabbb’

  • ANYSTRING

    启用@操作符。您可以使用@来匹配任何整个字符串。 您可以将@操作符与&和~操作符组合起来,创建一个“everything except”逻辑。例如:

    @&~(abc.+) # matches everything except terms beginning with ‘abc’

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

fuzzy 模糊搜索

混淆字符 (box → fox)

缺少字符 (black → lack)

多出字符 (sic → sick)

颠倒次序 (act → cat)

GET <index>/_search
{
  “query”: {
    “fuzzy”: {
      “<field>”: {
        “value”: “<keyword>”
      }
    }
  }
}

  • value:(必须,关键词)

  • fuzziness:编辑距离,(0,1,2)并非越大越好,召回率高但结果不准确

    1. 两段文本之间的Damerau-Levenshtein距离是使一个字符串与另一个字符串匹配所需的插入、删除、替换和调换的数量

    2. 距离公式:Levenshtein是lucene的,es改进版:Damerau-Levenshtein,

                     axe=>aex Levenshtein=2,Damerau-Levenshtein=1

  • transpositions:(可选,布尔值)指示编辑是否包括两个相邻字符的变位(ab→ba)。默认为true。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

使用fuzziness来指定模糊的范围,ES对fuzziness的的值最高只支持到2,过高的计算距离会导致过高的性能开销。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

fuzziness也可以在match中支持使用

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

 match的优势在于支持分词的模糊搜索,fuzzy不支持分词。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

“transpositions”: false – 使用Levenshtein计算距离

“transpositions”: true – 使用Damerau-Levenshtein计算距离

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

在数据量特别大的时候,不推荐使用fuzzy进行模糊搜索。

match_phrase_prefix 短语前缀

如果要使用match_phrase进行搜索的话,必须同时满足下面3个条件,缺1不可:

  • match_phrase会分词
  • 被检索字段必须包含match_phrase中的所有词项并且顺序必须是相同的
  • 被检索字段包含的match_phrase中的词项之间不能有其他词项

而match_phrase_prefix与match_phrase虽然有很多相同的地方,但是它多了一个特性:就是它允许在文本的最后一个词项(term)上的前缀匹配。如果是一个单词,比如a,它会匹配文档字段所有以a开头的文档;如果是一个短语,比如 “this is ma” ,他会先在倒排索引中做以ma做前缀搜索,然后在匹配到的doc中做match_phrase查询。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

match_phrase_prefix参数

  • analyzer 指定何种分析器来对该短语进行分词处理
  • max_expansions 限制匹配的最大词项
  • boost 用于设置该查询的权重
  • slop 允许短语间的词项(term)间隔:slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配 什么是相隔多远? 意思是说为了让查询和文档匹配你需要移动词条多少次?

值得注意的是,max_expansions是分片级别的,也就是说即使将max_expansions设置为1,在每个分片中只匹配一个词项,如果有10个分片,就会在10个分片中分别都匹配一个,也就是一共匹配了10个,所以不等于说max_expansions设置为1,返回的结果就一定只有1个。

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

简单理解为,max_expansions设置的越小,返回的结果越少,性能越好;设置的越大,返回的结果越多,性能越差。

前面说了,使用match_phrase_prefix搜索词的顺序是不能颠倒的,但是使用slop参数可以允许指定范围内的搜索词的颠倒

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

 slop的值就是词项移动的距离。

N-gram、edge ngram

min_gram:创建索引所拆分字符的最小阈值
max_gram:创建索引所拆分字符的最大阈值
ngram:从每一个字符开始,按照步长,进行分词,适合前缀中缀检索
edge_ngram:从第一个字符开始,按照步长,进行分词,适合前缀匹配场景

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

使用ngram作为分词器

【手把手】ElasticSearch索引的批量操作及模糊智能搜索【手把手】ElasticSearch索引的批量操作及模糊智能搜索

使用match_phrase进行搜索是可以搜索到结果

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

但当搜索的词项的长度超过ngram作为分词器所创建索引最大长度时就搜索不到

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

同样低过ngram作为分词器所创建索引最小长度时也搜索不到

【手把手】ElasticSearch索引的批量操作及模糊智能搜索

看到这里也就明白了,使用ngram对每个分词后的词项创建索引,需要的磁盘空间相当巨大,带来的好处就是做模糊查询的时候可以极大的缩短搜索时间。不过ngram使用起来对磁盘空间的要求相当高,一般会使用edge-ngram来创建索引。因为edge-ngram只支持前缀搜索,而ngram不仅支持前缀搜索,还支持中缀和后缀搜索。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/111906.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!