顾名思义,best_field就是获取最佳匹配的field,另个可以通过tie_breaker来控制其他field的得分,boost可以设置权重(默认都为1)。

下面从宏观上来讲的简单公式:

score=best_field.score*boost+other_fields*boost.score*tie_breaker。

实际计算远比这个公式复杂得多,还要考虑分片因素、出现位置、文档长短等。

评分算法请参考:http://m.blog.csdn.net/article/details?id=50623948

假如有二个文档

doc1:

“title”: "我爱北京天安门,城上挂的是毛爷爷"
          "body": "北京西路有美女,哪位男神去采呢?"

doc2:
           "title" : "我的家在东北,松花江上唉"
            "body" : "北京东路99号益丰近天安门城楼"

查询如下:
            "bool" : { "should" : [ {"match" : {"title" : "北京东路" }}, { "match" : { "body" : "北京东路"}}]}

es返回的结果应该是什么呢?哪一个doc的得分更高一些?是不是跟预期一致?
      我们预期是希望doc2得分更高,因为相关性更强一些。
      其实不然,es的返回结果是doc1得分更高。why?
      看看es是如何计算score的吧。

(1)执行should中的两个match
    (2)叠加score
    (3)乘以match到的clause数目(召回文档)
    (4)除以所有clause数目(所有文档)

doc1中title和body中含有词干“北京”,因此两个match都成功
      doc2中显然只有一个match能成功

第三步中差距出来了,doc1是2,doc2则是1.因此doc1得分比doc2要高。
      其实这不是我们想要的结果。

这个例子中title和body是相互竞争的字段,我们想要的是最佳匹配,哪一个字段match的结果更好,就选用哪一个字段的score作为最终的score。
      所以我们采用dis_max-query:

意义是:返回match到任何一个子查询的doc,哪一个doc的match结果做好,作为最后的score。
      “query” : { "dis_max" : { "queries" : [ {"match" : {"title" : "北京东路"}}, {"match" : {"body" : "北京东路"}} ]}
      现在,查询结果是我们想要的了,虽然doc1匹配数为2,但doc2中匹配度更高,有“北京东路”完整内容匹配,真所谓狭路相逢,勇者胜。

新情况有出现了:如果我们沿用dis_max查询“天安门美女”呢?
      结果显示为doc1跟doc2是一样的score。原因在于:dis_max之选用单个最好匹配的score作为最后的score,二个文档中都包括了“天安门”。
      doc1虽然title匹配了“天安门”,doby匹配了“美女”,但取最佳匹配也只能得1分,跟doc2相同。

显然这也不是我们想要的结果,我们觉得doc2得分应该高一些?如何调节?

我们需要综合考虑所有能match到的查询,同时还得考虑到最佳match的查询,因此tie_breaker参数出现了。

配合tie_breaker参数,score的计算过程是专业的

(1)获取最佳匹配的score

(2)获取其他匹配的score,乘以tie_breaker

(3)两者相加,规范化,作为score值

tie_breaker的参数值要同时考虑到最佳match和所有match,推荐0.1---0.4,如果是0的话,就只考虑最佳match了

multi_match query提供了上边的机制,通过制定type实现相同的效果:best_fields, most_fields,cross_fields.默认是best_field。

如下dis_max的query:

{ "dis_max" : { "queries" : [ { "match" : { "titile" : { "query" : "天安门美女", "minimun_should_match" : "50%" } } }, { "match" : { "body" : { "query" : "天安门美女", "minimun_should_match" : "30%" } } } ], "tie_breaker" : 0.3 } }

可以用下面的multi_match query代替:

{
"multi_match" : {
"query" : "天安门美女",
"type" : "best_fields",
"tie_breaker" : 0.3,
"fields" : [ "title", "body" ],
"minimun_should_match" : "30%"
}
}

fields字段支持通配符和单个字段提升boost(^),下面举个例子更清晰点,假如搜索关键字为“美女城楼”,首先会提取词干为“美女”,“城楼”

doc1与doc2分别是body与title各匹配一个,分值相同,若我们在title上加个权重,则会打破这分值,虽然匹配值一样,但加上权重,则doc2分值更高。

{
"multi_match" : {
"query" : "美女城楼",
"type" : "best_fields",
"tie_breaker" : 0.3,
"fields" : [ "title^1.5", "body" ],
"minimun_should_match" : "30%"
}
}

Elasticsearch搜索之best_fields分析的更多相关文章

  1. Elasticsearch搜索之cross_fields分析

    cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很 ...

  2. Elasticsearch搜索之most_fields分析

    顾名思义,most_field就是匹配词干的字段数越多,分数越高,也可设置权重boost. 下面是简易公式(详细评分算法请参考:http://m.blog.csdn.net/article/detai ...

  3. 一次 ElasticSearch 搜索优化

    一次 ElasticSearch 搜索优化 1. 环境 ES6.3.2,索引名称 user_v1,5个主分片,每个分片一个副本.分片基本都在11GB左右,GET _cat/shards/user 一共 ...

  4. ElasticSearch搜索介绍四

    ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, &quo ...

  5. elasticsearch indices.recovery 流程分析(索引的_open操作也会触发recovery)——主分片recovery主要是从translog里恢复之前未写完的index,副分片recovery主要是从主分片copy segment和translog来进行恢复

    摘自:https://www.easyice.cn/archives/231 elasticsearch indices.recovery 流程分析与速度优化 目录 [隐藏] 主分片恢复流程 副本分片 ...

  6. ElasticSearch 线程池类型分析之 ExecutorScalingQueue

    ElasticSearch 线程池类型分析之 ExecutorScalingQueue 在ElasticSearch 线程池类型分析之SizeBlockingQueue这篇文章中分析了ES的fixed ...

  7. ElasticSearch 线程池类型分析之 ResizableBlockingQueue

    ElasticSearch 线程池类型分析之 ResizableBlockingQueue 在上一篇文章 ElasticSearch 线程池类型分析之 ExecutorScalingQueue的末尾, ...

  8. Elasticsearch搜索资料汇总

    Elasticsearch 简介 Elasticsearch(ES)是一个基于Lucene 构建的开源分布式搜索分析引擎,可以近实时的索引.检索数据.具备高可靠.易使用.社区活跃等特点,在全文检索.日 ...

  9. 看完这篇还不会 Elasticsearch 搜索,那我就哭了!

    本文主要介绍 ElasticSearch 搜索相关的知识,首先会介绍下 URI Search 和 Request Body Search,同时也会学习什么是搜索的相关性,如何衡量相关性. Search ...

随机推荐

  1. 每天一个Linux命令 5

    命令名称:touch 功能描叙:创建空文件 格式:touch  文件名 范例:$touch japan.list(当前路径创建) $touch  /root/japan.list(指定路径创建) $t ...

  2. 关于nodeJS多线程的支持,目前看来无法实现,讲解v8的一些东西

    关于这个,我这几天一直在研究,国内关于v8的资料很少,stackoverflow上也不多. 说起来我得说声抱歉,虽然并没有承诺什么.这个功能大概是无法实现.下面我来解释一下为什么. 首先我们要了解一下 ...

  3. 1664: [Usaco2006 Open]County Fair Events 参加节日庆祝

    1664: [Usaco2006 Open]County Fair Events 参加节日庆祝 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 255  S ...

  4. 1578: [Usaco2009 Feb]Stock Market 股票市场

    1578: [Usaco2009 Feb]Stock Market 股票市场 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 414  Solved: 1 ...

  5. ajax实现分页和分页查询

    之前有写过ajax的加载页面,是非常简单的,而且不需要重新刷新页面,写起来也是非常的方便,今天写的分页是不用封装page.class.php的, 是单纯的js和ajax写出来的  首先为了页面的整齐与 ...

  6. android添加权限--eclipse

    首先进入清单文件 2.点击下面的permissions----Add 3.选择Uses permission-----OK 4.选择需要的权限 5.查看代码,,已经添加完毕

  7. Exchange无法发送邮件 未找到匹配的连接器来路由外部收件人解决办法

    使用命令行管理程序创建发送连接器 本示例创建发送连接器,用于集线器传输服务器 HubA 向 Internet 发送电子邮件.   复制 New-SendConnector -Name "In ...

  8. 零件库管理信息系统设计--part03:管理员登录部分设计

    兄弟们,我又回来啦! 上次我把表建完了.今天来点干货,我们用ssm框架来先简单实现一下管理员的登录功能. 在实现之前,我对user表(管理员表)做了些简单的修改,先来看看: 忽略哪些蓝色的马赛克和乱输 ...

  9. Java 学习文章汇总

    目前JAVA可以说是产业界和学术界最热门的语言,许多人都很急切想把JAVA学好. 但学习是需要步骤的,除非像电影中演的那样,能够把需要的专业技巧下载到脑海:主角只花了几秒下载资料,就马上具备飞行员的技 ...

  10. 工作中的趣事:聊聊ref/out和方法参数的传递机制

    0x00 前言 我在之前的游戏公司工作的时候,常常是作为一只埋头实现业务逻辑的码农.在工作之中不常有同事会对关于编程的话题进行交流,而工作之余也没有专门的时间进行技术分享.所以对我而言上家虽然是一家游 ...