常用的检索类型
在mysql中,我们常用的查询 可能就是 精准查询 模糊查询 范围查询 等等,那么在es中,有哪些是我们经常用到的呢?
term query(精准匹配)
我们先了解一下keyword和text类型的区别
keyword类型不会被分词的,适用于 标题 邮件 手机号 等,text会被分词,适用于描述 关键字 内容等-
总结
term 和match,match_phrase查询 keyword 必须要完全匹配
term查询text text分词中必须包含term
-
这里附带说一句,精准匹配,其实是不需要再计算评分的,我们可以使用 constant_sore来跳过评分阶段
match
match 查询text,因为两个都会分词,所以只要分词结果中有交集 就会显示
match_phrase
match_phrase 是分词的,text 也是分词的,但是 text的分词必须全部包含match_phrase的全部分词才会展示,但是必须是连续有序的,可以简单理解为,搜索关键词a ,那么在text字段中必须包含a 才会展示
布尔过滤器
must
里面的条件语句必须全部匹配
-
下面我查询一个 标题中包含 华为 并且价格是2999的手机
must_not
所有的条件语句都不能匹配
-
接下来我查询 标题不是华为 并且 价格也不是2999的手机
should
至少满足里面的一个条件
- 接下来我查询一个 标题是华为 或者 价格是2999的手机
[图片上传失败...(image-be1342-1637326113837)]
filter
返回的文档必须满足filter子句的条件。但是跟Must不一样的是,不会计算分值, 并且可以使用缓存,如果只看查询的结果,must和filter是一样的。区别是场景不一样。如果结果需要算分就使用must,否则可以考虑使用filter。
为了说明filter查询高效的原因,我们需要引入ES的一个概念query context和filter context。
query context关注的是,文档到底有多匹配查询的条件,这个匹配的程度是由相关性分数决定的,分数越高自然就越匹配。所以这种查询除了关注文档是否满足查询条件,还需要额外的计算相关性分数.
filter context关注的是,文档是否匹配查询条件,结果只有两个,是和否。没有其它额外的计算。它常用的一个场景就是过滤时间范围。
对于bool查询,must使用的就是query context,而filter使用的就是filter context。
[图片上传失败...(image-8e2ee9-1637326113837)]
其他常见查询
多个值精确查找
- 查找标题是 华为手机 和华为手机se的文档
GET test/_search
{
"query": {
"terms": {
"title.keyword": [
"华为手机",
"华为手机se"
]
}
}
}
范围检索
-
范围查询一定要注意类型,之前遇到过一次,我按日期查询一直查询不到,最后发现是同事把 date 设置成了int类型
是否存在字段
-
这种是不需要评分的,直接用filter 就可以了
前缀检索
- 查询华为开头的文档
GET test/_search
{
"query": {
"prefix": {
"title": "华为"
}
}
}
通配符检索
- 下面查询标题里面有手机的文档
GET test/_search
{
"query": {
"wildcard": {
"title": "*手机*"
}
}
}
正则表达式检索
-
支持正则匹配
模糊检索
- 模糊查询包含手机的文档
GET test/_search
{
"query": {
"fuzzy": {
"title": "手机"
}
}
}
ids检索
[图片上传失败...(image-116b03-1637326113837)]
其他相关参数
多字段匹配
-
查询title和content里面包含稻香的文档
字符串检索
- 查询文档中包含 稻香 美好和哈哈
[图片上传失败...(image-4eae05-1637326113837)]
简化字符串建搜
支持的操作如下:
1)+表示AND操作
2)| 表示OR操作
3)- 否定操作
4)*在术语结束时表示前缀查询
5)(和)表示优先
-
包含稻香 美好或者哈哈
高亮显示
我们使用谷歌或者百度搜索的时候,返回的结果往往会对我们搜索的关键字标红显示,那么es 搜索是怎么实现这个功能的呢
[图片上传失败...(image-d16e32-1637326113837)]
排序
- 注意:text字段一般不支持排序,如果有必要需要开启fielddata,或者给text字段设置其他字段类型
GET test/_search
{
"query": {
"match": {
"title": "手机"
}
},
"highlight" : {
"fields" : {
"title": {"type" : "plain"}
}
},
"sort": [
{
"_id": {
"order": "desc"
}
}
]
}
-
分页
使用match_phrase 搜索不到
- 我举个栗子
-
[图片上传失败...(image-586374-1637326113837)]
这是什么问题呢?我们来看一下存储的时候,这段话会被分词器解析成什么
[图片上传失败...(image-cf5746-1637326113837)]
-
我们发现,一篇文章 被解析成了 a,b,c 而我们的关键词被解析成了 1,2,3,完全对不上啊。这个情况下怎么办呢?
1.增加拓展词
2.增加should条件,比如下面这种
文档评分
- 我们搜索的时候一般是有排序的,按时间 或者按 排序字段 ,如果没有指定排序字段,那么es 默认是按照score的高低进行默认排序。
- Elasticsearch是基于Lucene的,所以它的评分机制也是基于Lucene的。在Lucene中把这种相关性称为得分(score),确定文档和查询有多大相关性的过程被称为打分(scoring)。
- ES最常用的评分模型是 TF/IDF和BM25,TF-IDF属于向量空间模型,而BM25属于概率模型,但是他们的评分公式差别并不大,都使用IDF方法和TF方法的某种乘积来定义单个词项的权重,然后把和查询匹配的词项的权重相加作为整篇文档的分数。
多文档score的调整
其实在应用中,有时候我们需要优化文档的评分,比如对两个索引,indexa 和indexb 我们可能先要优先返回indexb的数据(可能indexb是权威数据或者力推的数据),这个时候我们就要修改权重
[图片上传失败...(image-6e105-1637326113837)]或者有这样一种情况,你搜索文章的标题和内容中包含 某个关键词,但是 首先展示标题匹配的
- 此处注意score的最后得分其实是原始score*boost ,所以大于1是提升,小于1是降低