Elasticsearch 基本使用(三)条件查询_es条件查询,2024年最新值得一看

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

}
}


##### 标记数据匹配的条件


查询结果还可以标记当前记录,匹配上了哪些条件  
 在查询中,指定查询条件值时:  
 **\_name**标记当前条件  
 实际测试下来,不同查询方式,写法还不太一样


* term



“term”: {
“age”: {
“value”: “30”,
“_name”: “age”
}
}


* terms



“terms”: {
“age”: [“30”],
“_name”: “age”
}


* match



“match”: {
“name”: { 字段名
“query”: “四”,
“_name”: “name”
}
}


![在这里插入图片描述](https://img-blog.csdnimg.cn/965cc62bf4434e5dbf28fab441b722c5.png)  
 可以看到最后有一个 **matched\_queries**字段,说明本条记录是匹配了哪些条件。  
 **但是,这个机制好像对嵌套查询没效果,后续有机会再了解**


##### bool 子元素区别


* must: 与 (内部做与运算)
* must\_not:非(内部做 与 运算,最后在外层做非运算)**不进行相关性评分,不影响整体评分**
* should:或 (内部做 或运算)
* filter 过滤器,单纯过滤,**先于** 上述条件执。,**不进行相关性评分,不影响整体评分**,会使用过滤器缓存。速度更快。  
 **每个元素内部,还可以嵌套复杂条件(再来一层bool)**


#### boosting 查询(人为降低指定条件得分)


在bool查询中,我们的查询结果是将 bool 内部的所有条件做 **与运算**,  
 所有都匹配的数据会查出来,并根据相关性进行计分,默认倒序排列。  
 而 **boosting** 查询,则是  
 先根据 **positive**下的条件查询结果并得出一个初始评分,  
 再根据**negative** 下的条件匹配查询结果,如果匹配上了,则再根据**negative\_boost**的值对其进行降分的处理,使其排名降低。



boosting 查询

GET /stu/_search
{
“query”: {
“boosting”: {
“positive”: {
“match_phrase”: {
“name”: {
“query”: “张三”,
“_name”: “name”
}
}
},
“negative”: {
“term”: {
“age”: {
“value”: “30”,
“_name”: “age”
}
}
},
“negative_boost”: 0.2
}
}
}


**简单总结,就是 以 positive 查询数据,再以 negative + negative\_boost 对结果降分**


#### constant\_score 查询(固定得分)


普通的查询相关性分数是es根据相关性确定的,在此基础上,我们可以通过**boosting**查询降低匹配特定指标的分数。  
 还有一种,我们可以返回固定分数。  
 通过前面的学习,我们知道在 bool 查询中 filter 和 must\_not 是不计算分数的;因此 **constant\_score**查询其实就是通过 **filter**查询,然后为其指定固定分数实现。



constant_score 查询

GET /stu/_search
{
“query”: {
“constant_score”: {
“filter”: { # 查询条件
“term”: {
“age”: “30”
}
},
“boost”: 1.2 # 固定分数
}
}
}


#### dis\_max 查询(单条件 最高分)


其他查询,最终得分是由所有query综合得分构成。  
 而dis\_max 查询**只取评分最高的那一项查询,而忽略其他条件的评分**  
 以下条件查询 name 匹配 张三 **或者** hobbies 包含 book 的用户



GET /stu/_search
{
“query”: {
“dis_max”: {
“queries”: [
{
“match”: {
“name”: “张三”
}
},
{
“match”: {
“hobbies”: “book”
}
}
]
}
}
}


得到以下得分



"hits" : [
  {
    "\_index" : "stu",
    "\_type" : "\_doc",
    "\_id" : "jToE7YgBKFUjhQBivmyC",
    "\_score" : 0.9983525,
    "\_source" : {
      "id" : 1,
      "name" : "张三",
      "age" : 10,
      "hobbies" : [
        "swimming",
        "walk",
        "drive"
      ],
      "address" : [
        {
          "province" : "500",
          "city" : "023",
          "county" : "1991"
        },
        {
          "province" : "501",
          "city" : "024",
          "county" : "1992"
        }
      ]
    }
  },
  {
    "\_index" : "stu",
    "\_type" : "\_doc",
    "\_id" : "jzoE7YgBKFUjhQBi\_2zu",
    "\_score" : 0.9808291,
    "\_source" : {
      "id" : 3,
      "name" : "张三四",
      "age" : 30,
      "hobbies" : [
        "movie",
        "book",
        "swimming"
      ],
      "address" : [
        {
          "province" : "600",
          "city" : "021",
          "county" : "1887"
        },
        {
          "province" : "601",
          "city" : "073",
          "county" : "1953"
        }
      ]
    }
  }
]



| 条件 | 得分 |
| --- | --- |
| 张三\_name | 0.9983525 |
| 张三\_hobbies | 0 |
| 张三四\_name | 0.8416345 |
| 张三四\_hobbies | 0.9808291 |


**可以看到,第一条记录虽然只匹配上了 name = 张三,但是它的得分是 0.9983525,  
 而第二条记录虽然匹配上了两个条件 ,但是单算 name = 张三四 的评分只有 0.8416345,而 单算 hobbies 含有 book 的得分为 0.9808291,因此第二条记录采用了 较高匹配度的 hobbies 的得分。  
 总体算下来,低于第一条**


##### 算上其他 query 的得分


只使用 dis\_max 会完全忽略其他query条件的得分,可能导致最终结果,不准确;因此,我们可以算上其他query的得分。  
 通过 参数 **tie\_breaker** 来指定其他query得分的缩小比例,取值范围 [0, 1],当这个值为1时,其效果了 bool 查询一致。


这里我们将缩小比例设置为0.7,再看看查询的结果



GET /stu/_search
{
“query”: {
“dis_max”: {
“queries”: [
{
“match”: {
“name”: “张三”
}
},
{
“match”: {
“hobbies”: “book”
}
}
],
“tie_breaker”: 0.7
}
}
}


![在这里插入图片描述](https://img-blog.csdnimg.cn/f61e642fccc04d27b0d9cae028fe149f.png)  
 可以看到,张三四 在 hobbies 的基础之上,加上 name 的分数已经超越了 张三。  
 再结合上面表格单项得分,**“tie\_breaker”: 0.7**  
 张三得分 = 0.9983525 + 0 = 0.9983525  
 张三四得分 = 0.9808291 + 0.8416345 \* 0.7 = 1.56997325  
 与上图相符。


#### function\_score 查询


使用函数自定义评分逻辑;可以使用内置函数或脚本完全自定义评分逻辑。  
 内置函数


* weight 对当前分值做 **乘法**,实现 增加或减少
* random\_score :生成随机分数
* field\_value\_factor :将文档指定字段(数值或者可转化为数值)纳入得分计算。
* 衰减函数 - linear,exp,gauss 等
* script\_score 使用脚本,完全自定义评分逻辑


我们还可以使用 **functions** 为不同匹配条件指定不同的计分逻辑;匹配上了执行对应的计分逻辑,**未匹配上的得1分,未匹配上的数据也会展示出来**  
 functions 外面的查询及其评分只展示匹配上的数据;如果外面没有过滤,只在 functions 内进行查询和评分,那么评分逻辑只作用于匹配上的数据,未匹配上的数据统统1分  
 自定义函数有个计分计算方式字段 **“boost\_mode”: “multiply”** 默认是乘法(weight及field 方式都是乘以现有分数)。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6ce9d312e65e4c5fb84bf521f04f4161.png)


##### weight 成倍增减现有得分



GET /stu/_search
{
“query”: {
“function_score”: {
“query”: {
“match”: {
“name”: “张三”
}
},
“weight”: 0.5,
“boost_mode”: “multiply”
}
}
}


两条数据  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f1c06aa0898f42dda142378ee1b6e403.png)


##### random\_score 随机得分



GET /stu/_search
{
“query”: {
“function_score”: {
“query”: {
“match”: {
“name”: “张三”
}
},
“random_score”: {}
}
}
}


两条数据,随机得分  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/404f4f08cc1f40c2ad0b1381ebe06b53.png)


##### 指定字段(数值或者可转为数值)纳入计分



GET /stu/_search
{
“query”: {
“function_score”: {
“query”: {
“match”: {
“name”: “张三”
}
},
“field_value_factor”: {
“field”: “age”
}
}
}
}


以下得分 = 现有得分 \* 字段值 (age)\* 比例(factor 默认为1) = **0.9983525 \* 30 \* 1** = 25.249035  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e139f843f2954219aa843671d40b8fd1.png)


##### 自定义脚本得分


使用脚本完全自定义得分逻辑


###### 直接以age为得分


script\_score.script :指定得分计算方式,直接取 age 的值  
 boost\_mode:replace;默认是 multiply,还是与age做乘法;使用replace,则是直接替换原有的分数而不做乘法。



直接以age得分

GET /stu/_search
{
“query”: {
“function_score”: {
“query”: {
“match”: {
“name”: “张三”
}
},
“script_score”: {
“script”: “doc[‘age’].value”
},
“boost_mode”: “replace”
}
}
}


因此得到分数分别为二者的 age  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5312004a68b342ee9797fb824c2a6ada.png)








**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://img-blog.csdnimg.cn/img_convert/f1107248b9da9b136561b42a7f60baeb.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

pt": "doc['age'].value"
      },
      "boost\_mode": "replace"
    }
  }
}

因此得到分数分别为二者的 age
在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-6wh0mNkN-1713120350780)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch使用深度分页功能需要注意以下几点: 1. 尽量避免使用深度分页功能,因为它会增加网络和计算开销,可能导致性能问题。 2. 深度分页功能是通过设置 from 和 size 参数来实现的。from 参数表示从哪个位置开始查询,size 参数表示每页返回的文档数量。 3. Elasticsearch 默认最多只能返回 10000 条记录,如果需要查询更多的记录,需要设置 index.max_result_window 参数。但是设置太大会占用过多的内存,影响性能。 下面是一个 Java 实现 Elasticsearch 分页查询的示例代码: ``` import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; public class ESQuery { private Client client; public ESQuery(Client client) { this.client = client; } public void search(String index, String type, int from, int size) { SearchResponse response = client.prepareSearch(index) .setTypes(type) .setQuery(QueryBuilders.matchAllQuery()) .addSort(SortBuilders.fieldSort("_id").order(SortOrder.DESC)) .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) .setFrom(from) .setSize(size) .execute() .actionGet(); SearchHits hits = response.getHits(); for (SearchHit hit : hits) { System.out.println(hit.getSourceAsString()); } } } ``` 调用示例: ``` ESQuery esQuery = new ESQuery(client); esQuery.search("my_index", "my_type", 0, 10); // 查询第一页,每页10条记录 esQuery.search("my_index", "my_type", 10, 10); // 查询第二页,每页10条记录,从第11条记录开始 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值