elasticsearch学习笔记高级篇(九)——多shard场景下相关度分数不准确问题

智码探险家
• 阅读 1886

场景分析:

在某个shard中,有很多个document包含了title中有java这个关键字,比如说10个doc的title中包含了java。

当一个搜索title包含java的请求到这个shard的时候,应该会这么计算relevance score相关度分数。TF/IDF算法:

(1)在一个document的title中java出现了几次
(2)在所有的document的title中,java出现了几次
(3)这个document的title的长度
由于shard只是一部分的document,默认情况下就在shard本地计算IDF。当有多个shard的时候,比如在一个shard中,只有一个document title包含java,此时计算shard local IDF就会分数很高,导致相关度分数很高。这就有可能导致出现的搜索结果,似乎不太是你想要的结果。也许相关度很高的doc排在了后面,分数不高,而相关度很低的doc排在了前面,分数很高。

如何解决该问题

(1)在生产环境下,数据量大,尽可能实现均匀分配
数据量很大的话,在概率学的背景下,elasticsearch都是在多个shard中均匀路由数据的,路由的时候根据_id,实现负载均衡。
比如说有10个document,title都包含java,一共有5个shard,那么在概率学的背景下,如果负载均衡的话,其实每个shard都应该有2个doc,title包含java。如果说数据分布均匀的话,其实就没有因为IDF不准确导致相关度分数不准确的问题。
(2)测试环境下,将索引的primary shard设置为1个
如果说只有一个shard,那么当然所有的document都在这个shard里面,也就没有没有因为IDF不准确导致相关度分数不准确的问题。
(3)测试环境下,搜索附带search_type=dfs_query_then_fetch参数
带上search_type=dfs_query_then_fetch参数,就会将local IDF取出来计算global IDF。也就是在计算一个doc的相关度分数的时候,就会将所有shard对local IDF计算一下,获取出来在本地进行global IDF分数的计算,此时会将所有shard的doc作为上下文来进行计算,可以保证准确性,但是生产环境下,不推荐这个参数,因为性能很差。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Spring Boot与Kotlin 整合全文搜索引擎Elasticsearch
Elasticsearch在全文搜索里面基本是无敌的,在大数据里面也很有建树,完全可以当nosql(本来也是nosql)使用。这篇文章简单介绍SpringBoot使用Kotlin语言连接操作Elasticsearch。但是不会做很详细的介绍,如果要深入了解Elasticsearch在Java/kotlin中的使用,请参考我之前编写的《Elastic
Wesley13 Wesley13
3年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Stella981 Stella981
3年前
Object类
作为万类之首的Object类,我们有必要详细全面的了解一下。Object类定义在Object.java文件,属于包java.lang。Object类有一个私有方法privatestaticnativevoidregisterNatives().native是java语言的一个关键字.使用native关键字说明这个方法是原生函数,也就是这个
Wesley13 Wesley13
3年前
Java中不同包下类与类之间的访问
Java中不同包下类与类之间的访问(1)我们多次使用一个带包的类,都需要加包的全路径,非常的麻烦,这个时候,Java就提供了导包的功能,提供了一个关键字import。(2)格式:import包名.包名....包名.类名;这种方式导入的是:到类的名称。另一种:imp
Stella981 Stella981
3年前
MongoEngine文档 新手教程 Document实例
Document实例创建一个新的document对象,创建一个相关document类的实例,可以在字段的构造器中赋值。你可以在任何document里面的字段设置值;\python\ 1.\ page  Page(title"Test Page")2.\ page.title3
Stella981 Stella981
3年前
Mongodb 分片与副本集
测试搭建192.168.3.110mongos30000,30001,30002config40000,40001,40002shard150001,50002,50003shard250004,50005,50006,shard350007,50008,50009\root@mysqlslave10
Wesley13 Wesley13
3年前
Java 日期与时间
Java的日期Java没有内置的日期类,但可以导入java.time包,这个包中包含了许多类,可用于处理日期和时间。例如:<table<tbody<tr<thstyle"width:25%"Java类</th<thstyle"width:75%"描述</th</tr<tr<td<code
Stella981 Stella981
3年前
PyCharm 下引入anaconda的模块
搞科学计算和人工智能的人都会需要很多python模块例如:Numpy,Panda....anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项因为包含了大量的科学包,Anaconda的下载文件比较大,如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(
ElasticSearch集群灾难:别放弃,也许能再抢救一下 | 京东云技术团队
1前言Elasticsearch作为一个分布式搜索引擎,自身是高可用的;但也架不住一些特殊情况的发生,如:集群超过半数的master节点丢失,ES的节点无法形成一个集群,进而导致集群不可用;索引shard的文件损坏,分片无法被正常恢复,进而导致索引无法正常