Elasticsearch系列(13)Query之全文查询

全文查询(Full text queries)能够搜索已分析的text字段,如电子邮件的正文。全文查询支持以下方式的查询:

elasticsearch模糊匹配 es查询模糊匹配语句elasticsearch模糊匹配 es查询模糊匹配语句


elasticsearch模糊匹配 es查询模糊匹配语句


匹配(match)查询返回与字段匹配的文档,支持字段类型包括文本、数字、日期或布尔值,对于文本值,在匹配之前对所提供的文本需进行分析。简单示例如下:

查询文本值“Brown Fox”,字段经过分析器分析后的分词(Brown和Fox),在文档字段值上必须全部匹配,示例如下:

查询文本值“Foaax”,模糊匹配查询,允许2个编辑距离,可以匹配到“Fox”,示例如下:

定义停止词过滤器“my_stop_words_filter”, 将zero_terms_query设置为all,match查询停用词,预期返回所有文档,示例如下:

匹配布尔前缀(match_bool_prefix)查询会首先分析输入的文本值,然后将分词后词条构造一个bool查询,除了一个词条外,每个词条都在term查询中使用,一个词条用于前缀查询。示例如下:

匹配文档字段content中包含“Quick”或前缀为“Brow”的文档,返回结果片段:

匹配短语(match_phrase)查询分析文本并且从分析的文本中创建一个短语查询。

匹配短语查询,在content字段中查询文本“White Fox”,不会拆分“White Fox”,如果文档中content字段包含“White Fox”,那么此文档匹配成功返回,示例如下:

返回结果片段如下:

匹配短语前缀(match_phrase_prefix)查询返回包含所输入文本中单词的文档,其顺序与所输入的相同,所输入的文本的一个词被视为前缀,并且返回的文档必须包含与该词开头的匹配的词条。

返回结果片段如下:

多值匹配(multi_match)查询建立在匹配(match)查询之上,允许多字段查询。

例如,在字段“content”或“user.name”上,查询文本“White Fox”,示例如下:

fields支持通配符查询。例如,在后缀为name的所有字段中查询,示例如下:

fields支持通过插入符号(^) 来提升单个字段。例如,content字段的相关性比字段user.name重要3倍,示例如下:

multi_match查询内部执行的方式取决于类型参数,其类型参数值包括:

首先创建索引my_index_03并且索引数据,示例如下:

most_fields使用示例如下:

phrase_prefix使用示例如下:

类似于

查询字符串(query_string)查询根据作符(如AND或NOT)来解析和分割所提供的查询字符串,然后分析每个分割文本,返回匹配的文档,query_string查询严格按照查询语法,如果查询字符串包含任何无效语法,则返回错误。

例如,在my_index_03索引content字段上,查询“Brown”或“Quick White”文本值,示例如下:

通配符搜索可以在单个词条上运行,使用?替换单个字符,替换零个或多个字符:

Qu?ck Bro

正则表达式模式可以嵌入到查询字符串中,使用前斜杠中("/")包装:

content:/Qu.c[ki]/

使用模糊作符进行模糊查询,默认编辑距离是2:

Quikc~

可修改编辑距离来控制拼写错误范围,如下修改编辑距离为1:

Quikc~1

可以为日期、数字或字符串字段指定范围。包含范围用方括号[min TO max]指定,排除范围用大括号{min TO max}指定。

使用boost作符^使一个词条比另一个词条更相关。

默认情况下,只要有一个词条匹配,整个文档匹配。不过可以通过布尔作符来更细粒度的控制。

作符是+(该词条必须存在)和-(该词条必须不存在),其他词条可选的,例如,查询Fox必须存在、White必须不存在,示例如下:

Quick +Fox -White

多个词条或子句可以用括号组合在一起,形成子查询:

message:(Brown OR Fox) content:(White Fox)^2

如果需要在查询中使用作为作符的字符(而不是作为作符),那么应该使用前导反斜杠“”对它们进行转义。例如,要搜索 (1+1)=2 ,需要将查询编写为 (1+1)=2 ,当为请求体使用JSON时,需要两个前面的反斜杠( )。

可以使用fields参数在多个字段之间执行query_string搜索(用法参考多值匹配查询)。

简单查询字符串(_query_string)查询使用具有有限但容错语法的解析器,根据提供的查询字符串返回匹配文档。

它的语法比query_string查询简单,但是_query_string查询不会返回无效语法的错误。相反,它忽略查询字符串中任何无效的部分。

示例如下:

_query_string支持下列作符:

根据匹配词条的顺序和接近度返回文档。间隔(intervals)查询使用一系列定义组成的匹配规则,将这些规则应用于来自指定字段的词条。

简单示例如下:

匹配(match)规则匹配分析的文本。

前缀(prefix)规则用来匹配以指定的一组字符开头的词条,这个前缀可以扩展到最多匹配128个词条,如果前缀匹配超过128词条,Elasticsearch将返回一个错误,可以在字段映射中使用index-prefixes选项来修改此限制。

通配符(wildcard)规则使用通配符模式匹配词条。此模式可以扩展到最多匹配128项,如果模式匹配超过128项,Elasticsearch将返回一个错误。

模糊(fuzzy)规则在由模糊性定义的编辑距离内匹配与所提供的词条相似的词条。如果模糊展开匹配的项超过128项,Elasticsearch将返回一个错误。

all_of规则返回跨其他规则组合的匹配项。

any_of规则返回其任一个子规则生成的intervals。

过滤(filter)规则基于查询返回间隔(intervals)。

下面的intervals查询中包含一个match规则,规则定义了查询文本为“Quick Fox”, 单词 Quick 和 Fox 之间的位置不超过10,match规则里包含一个filter规则,用来排除字段含有单词“Brown”的文档,具体如下:

返回结果片段如下:

下面的intervals查询中包含一个match规则,match规则里包含一个filter规则,filter规则使用脚本来定义规则(根据间隔的开始位置、结束位置和内部间隔计数来筛选间隔),具体如下:

下面的intervals查询中包含一个match规则,规则定义了查询文本为“Fox”,match规则里包含一个filter规则,filter规则使用contained_by参数定义了只查询“Brown Fox”的短语匹配,用其来过滤间隔,具体如下:

下面的intervals查询中包含子intervals,子intervals中包含两个match规则,具体如下:

Elasticsearch搜索Suggest功能优化

搜索时:如上图所示,可用户选择category,提升Suggest准确度

如:“天上人间” 分析为:“天上人间”、“天上”、“上人”、“人间” 四个词条。 要注意这4个词条还有顺序,也就是ition分别为0, 1, 2, 3。FST实际上是前缀编码,这些词被顺序串联在一起进行编码,并记录了每个词条的相对位置,编码后形如: 天上人间|天上|上人|人间 0 1 2 3

为了帮助理解,针对你的例子,可以试一下如下的搜索:

总结来说,当使用completion suggester的时候, 不是用于完成 类似于 " "这样的模糊匹配场景,而是用于完成前缀匹配的。 对于汉字的处理,无需使用ik/ HanLP一类的分词器,直接使用keyword yzer,配合去除一些不需要的stop word即可。

从搜索日志挖掘的Suggest词,可以根据搜索词的搜索频次作为热度来设置weight,Suggest会根据weight来排序。

es查询term,match,match_phase,query_string的区别

match :模糊匹配,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。

term : 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询"hello world",结果就相很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有"hello world"的字样,而不是查询字段中包含"hello world"的字样,elasticsearch会对字段内容进行分词,"hello world"会被分成hello和world,不存在"hello world",因此这里的查询结果会为空。这也是term查询和match的区别。

match_phase :会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that word不满足,world hello也不满足条件。

query_string :和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。

ES实现模糊搜索

最近使用ES时,有一个简单的需求,要求实现按照某个字段实现类似mysql中的like查询。

这里记录下实现方式。

这里ja的api使用的是RestHighLl,RestHighLl从字面意思理解就是restful风格的高级别的客户端,底层封装的是一个连接池,当需要执行 update、index、delete作时,直接从连接池中取出一个连接,然后发送请求到ElasticSearch服务端,服务端基于Netty接收请求。新版本的elasticsearch ja client 都用RestHighLl去连接ES集群。

以下为实现方式:

这里要实现模糊匹配的字段为:plateNo(业务上表示车牌号)

以下是一开始的实现方法。plateNo字段type为text,现在保存了一条值为京A00000的数据

刚开始时候一直无法实现,可以搜索 京 查询出数据;或者搜索 A00000 查询到数据,但是使用全部 京A00000 查询数据为空。

后来确定原因,因为为text,所以这个字段在保存时会分词,所以索引中不会有 京A00000,因此解决思路就是该字段type指定为keyword,同时使用查询时指定查询时使用keyword,如下。

boolQueryBuilder.must(QueryBuilders.wildcardQuery("plateNo.keyword", (" 京A00000 ")));

解决问题。

Elasticsearch实现模糊搜索、keyword忽略大小写

1、ngram分词器Elasticsearch实现模糊搜索

2、keyword忽略大小写

Controller

Serv

大小写兼容搜索,即字段内容为 alan ,搜索 alan 、 ALAN 、 Alan 都可以搜索出来。

根据 min_gram 以及 max_gram 指定切分时最小几个字符、几个字符。长度越短,切分出来越少,更多的被匹配到质量也越;长度越长,切分出来越多,匹配越。

如 min_gram 为1, max_gram 为1,对于 Quick 这个单词,就会变成[ Q,u,i,c,k]。按关键字 Qui 搜索,关键字就会被拆分成 Q , u 、 i 三个字母去搜索,可能就会搜索出: Quick 、 Query 、 your 、 like 等单词。

如 min_gram 为1, max_gram 为3,对于 Quick 这个单词,就会变成[ Q, Qu, Qui, u, ui, uic, i, ic, ick, c, ck, k ]。按关键字 Qui 搜索,只会去匹配包含 Qui 的单词,因此搜索结果只有 Quick

min_gram 默认值为1, max_gram 默认值为2, min_gram 与 max_gram 的值默认为1,如果设置值时值大于1,需要先设置 index.max_ngram_diff 参数。

一文带你搞懂Elasticsearch中的模糊查询

Elasticsearch 警惕使用 wildcard 检索!然后呢?

NGram Tokenizer

Elasticsearch Analysis 03 - Tokenizer