通过上一篇文章我们知道,在全文搜索的时候,系统会对检索内容进行分词,然后在对每个词项进行检索,但是我们今天介绍的基于词项查询的Api是不需要对输入内容进行分词的,Term Level Query会将输入的内容作为一个整体来进行检索,并使用相关性算法对包含整个检索内容的文档进行相关性算法
Term是文本经过分词器处理得出来的词项,是Es中表达语义的最小单位。ES中提供很多基于Term的查询功能,下面几个Api是我们今天将会介绍的:
- Term Query:返回在指定字段中准确包含了检索内容的文档
- Terms Query:跟Term Query类似,不过可以同时检索多个词项
- Range Query:范围查询
- Exist Query:返回在指定字段上有值的文档,一般用于过滤没有值的文档
- Prefix Query:返回在指定字段中包含指定前缀的文档
- Wildcard Query:通配符查询
Term Query Term Query Api返回在指定字段中准确包含了检索内容的文档,你可以使用此Api去查询精确值的字段,如书本Id、价格等,其示例如下:
![image.png](https://img-blog.csdnimg.cn/img_convert/61cbcc5c62ceda291fbe50a855625706.png)
返回结果:
![image.png](https://img-blog.csdnimg.cn/img_convert/24f4de4836a13067686da052c459692c.png)
需要注意的是,要避免将Term Query用在text类型的字段上,例如:
如上示例所示,我们的数据中确实有两个文档的书名里还有"linux",但是无法匹配上。
之前说过,基于Term的查询不会去检索内容进行分词的,输入的文本会作为一个整体进行查询。但是在索引数据的时候会进行分词并转换为小写(书名字段用了standard分词器,会进行小写转换),所以上述的列子是无法匹配任何文档的,只有小写的"linux"才可以匹配文档。如果要对text类型的字段进行搜索,应该使用match Api而不是使用Term Query Api
Terms Query
Terms Query的功能跟Term Query类似,不过可以同时索引多个词项的功能。例如我需要检索作者为"Stephen Hawking"或者"Wolfgang Mauerer"写的书的时候,可以这样做:
返回结果:
Range Query
Range Query Api可以查询字段值符合某个范围的文档数据。例如查询书本大于等于 10.0 小于20.0的书本信息。其示例如下:
返回结果:
如上所示,Range Query Api是比较简单的,在"range"字段中指定需要查询的文档字段,这里我们查询"price"字段,并且规定其值大于等于10.0,小于10.0。
Exist Query
使用Exist Query Api可以查询那些在指定字段上有值的文档,一般情况下使用这个Api来做文档过滤。
那么什么样的值才被认为是空值那?一个字段的值为空可能是由于下面这几个原因导致的:
- 字段的Json值为null或者[], 如果一个字段压根不存在于文档的_source里,也被认为是空的
- 一个字段在Mapping定义的时候设置了"index":false
- 一个字段的值的长度超过了Mapping里这个字段设置的ignore_above时
- 当字段的值不合规,并且mapping中的这个字段设置了ignore_malformed
使用示例如下:
返回结果:
返回结果:
这个查询是无法匹配任何文档的,因为mapping中没有定义"press"
Prefix Query
Prefix Query可以查询在指定字段中包含特定前缀的文档,其示例如下:
返回结果:
如上所示,使用了Prefix Query查询还有"linu"前缀的文档,如果书本名字中还有"linu"开头的词语的文档会被匹配上。需要注意的是,text类型的字段会被分词,成为一个个的term,所以这里的前缀匹配是匹配这些分词后的term
Wildcard Query
Wildcard Queyr允许使用通配符表达式进行匹配。Wildcard Queyr支持两个通配符:
- ?,使用 ? 来匹配任意字符。
- *,使用 * 来匹配 0 或多个字符。
使用示例如下:
如上示例,使用了Wildcard Query查询书名中含有"linu"开头的文档
**需要注意的是,Prefix Query和Wildcard Query在进行查询的时候需要扫描倒排索引中的词项列表才能找到全部匹配的词项,然后在获取匹配词项对应的文档Id。所以使用Wildcard Query的时候需要注意性能问题,要尽量避main使用左通配匹配模式,如"linux"、".linux"
使用Term Level Query Api进行结构化搜索
结构化搜索指的是对结构化的数据进行搜索。那什么是结构化数据那?你可以认为是高度组织、结构化的数据,例如日期、颜色、地区编码、价格等等
像书本的价格都是有精确的格式的,我们可以对这个数据进行逻辑操作,例如判读价格的范围。一般我们对结构化数据进行精确化匹配,而精确匹配的结果为布尔值,这个时候可以考虑跳过相关性算法的步骤,从而提高搜索性能
使用 Constant Score 可以将 query 转化为 filter,可以忽略相关性算分的环节,并且 filter 可以有效利用缓存,从而提高查询的性能。其示例如下
返回结果: