ES入门四:Term Query Api实践

通过上一篇文章我们知道,在全文搜索的时候,系统会对检索内容进行分词,然后在对每个词项进行检索,但是我们今天介绍的基于词项查询的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类型的字段上,例如:
image.png
如上示例所示,我们的数据中确实有两个文档的书名里还有“linux”,但是无法匹配上。
之前说过,基于Term的查询不会去检索内容进行分词的,输入的文本会作为一个整体进行查询。但是在索引数据的时候会进行分词并转换为小写(书名字段用了standard分词器,会进行小写转换),所以上述的列子是无法匹配任何文档的,只有小写的“linux”才可以匹配文档。如果要对text类型的字段进行搜索,应该使用match Api而不是使用Term Query Api

Terms Query

Terms Query的功能跟Term Query类似,不过可以同时索引多个词项的功能。例如我需要检索作者为“Stephen Hawking”或者“Wolfgang Mauerer”写的书的时候,可以这样做:
image.png
返回结果:
image.png

Range Query

Range Query Api可以查询字段值符合某个范围的文档数据。例如查询书本大于等于 10.0 小于20.0的书本信息。其示例如下:

image.png

返回结果:
image.png
如上所示,Range Query Api是比较简单的,在“range”字段中指定需要查询的文档字段,这里我们查询“price”字段,并且规定其值大于等于10.0,小于10.0。
image.png

Exist Query

使用Exist Query Api可以查询那些在指定字段上有值的文档,一般情况下使用这个Api来做文档过滤。
那么什么样的值才被认为是空值那?一个字段的值为空可能是由于下面这几个原因导致的:

  • 字段的Json值为null或者[], 如果一个字段压根不存在于文档的_source里,也被认为是空的
  • 一个字段在Mapping定义的时候设置了“index”:false
  • 一个字段的值的长度超过了Mapping里这个字段设置的ignore_above时
  • 当字段的值不合规,并且mapping中的这个字段设置了ignore_malformed

使用示例如下:
image.png
返回结果:
image.png

image.png
返回结果:
image.png
这个查询是无法匹配任何文档的,因为mapping中没有定义“press”

Prefix Query

Prefix Query可以查询在指定字段中包含特定前缀的文档,其示例如下:
image.png

返回结果:
image.png
如上所示,使用了Prefix Query查询还有“linu”前缀的文档,如果书本名字中还有“linu”开头的词语的文档会被匹配上。需要注意的是,text类型的字段会被分词,成为一个个的term,所以这里的前缀匹配是匹配这些分词后的term

Wildcard Query

Wildcard Queyr允许使用通配符表达式进行匹配。Wildcard Queyr支持两个通配符:

  • ?,使用 ? 来匹配任意字符。
  • *,使用 * 来匹配 0 或多个字符。

使用示例如下:
image.png
如上示例,使用了Wildcard Query查询书名中含有“linu”开头的文档

**需要注意的是,Prefix Query和Wildcard Query在进行查询的时候需要扫描倒排索引中的词项列表才能找到全部匹配的词项,然后在获取匹配词项对应的文档Id。所以使用Wildcard Query的时候需要注意性能问题,要尽量避main使用左通配匹配模式,如“linux”、“.linux”

使用Term Level Query Api进行结构化搜索

结构化搜索指的是对结构化的数据进行搜索。那什么是结构化数据那?你可以认为是高度组织、结构化的数据,例如日期、颜色、地区编码、价格等等

像书本的价格都是有精确的格式的,我们可以对这个数据进行逻辑操作,例如判读价格的范围。一般我们对结构化数据进行精确化匹配,而精确匹配的结果为布尔值,这个时候可以考虑跳过相关性算法的步骤,从而提高搜索性能
使用 Constant Score 可以将 query 转化为 filter,可以忽略相关性算分的环节,并且 filter 可以有效利用缓存,从而提高查询的性能。其示例如下

image.png
返回结果:
image.png

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要对百万数据的 Elasticsearch 索引进行重命名,可以尝试以下性能优化方法: 1. 执行重命名操作时,尽量避免在同一节点上同时执行其他繁重的操作,以减少节点的负载和竞争。 2. 可以考虑将索引分成多个分片,然后在多个节点上执行并行的重命名操作。这可以通过设置索引的分片数来实现,例如: ``` PUT /my_index/_settings { "index": { "number_of_shards": 5 } } ``` 这将将索引分成 5 个分片,每个分片都可以在不同的节点上处理。 3. 使用 Elasticsearch Bulk API 执行批量操作。Bulk API 可以一次性处理多个操作,从而提高索引重命名的性能,例如: ``` POST /_bulk { "update": { "_id": "1", "_index": "my_index", "_type": "_doc" } } { "doc": { "name": "new_name" } } { "update": { "_id": "2", "_index": "my_index", "_type": "_doc" } } { "doc": { "name": "new_name" } } ... ``` 这将在一次 API 调用中更新多个文档的名称,而不是逐个更新。 4. 在执行重命名操作之前,可以考虑关闭索引的刷新机制。刷新操作会将新数据写入磁盘,从而增加索引重命名的时间和开销。可以使用以下命令关闭索引的刷新机制: ``` POST /my_index/_settings { "index": { "refresh_interval": "-1" } } ``` 这将关闭索引的刷新机制。在执行完索引重命名操作后,可以使用以下命令重新启用刷新机制: ``` POST /my_index/_settings { "index": { "refresh_interval": "1s" } } ``` 这将每秒钟执行一次索引刷新操作。请注意,关闭刷新机制可能会导致某些查询结果不准确,因为查询可能会返回尚未刷新的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值