顾名思义,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. MySQL分区表的局限和限制

    禁止构建 分区表达式不支持以下几种构建: 存储过程,存储函数,UDFS或者插件 声明变量或者用户变量 可以参考分区不支持的SQL函数 算术和逻辑运算符 分区表达式支持+,-,*算术运算,但是不支持DI ...

  2. Linux部署与基本指令

    把以前写的linux发布一下下吧,写的真的好差劲... Linux部署   chmod:改变一个文件的权限 改变abc的权限为777 常用的权限: 777-644-755 ************** ...

  3. java利用“映射文件访问”(MapperByteBuffer)处理文件与单纯利用Buffer来处理文件的快慢比较

    处理文件是java经常使用的操作,在对一个“大文件”(比如超过64M)进行操作时一点点速度的提高都会带来性能的巨大提升.然而我们经常使用的BufferxxStream,来直接处理大文件时,往往力不从心 ...

  4. CRUD操作(20161017)

    上午: (7)范围查询 select * from car where price>40 and price<60 select * from car where price betwee ...

  5. python 接口自动化测试(三)

    1.WriteIni.py import ConfigParser cf = ConfigParser.ConfigParser() cf.add_section("PC_WSDL" ...

  6. Java的内存机制详解

    Java把内存分为两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间, ...

  7. web从入门开始(6)-----框架

    普通框架 框架概念:就是将一个页面分割成小窗口,每个窗口都是一个网页 框架集和框架页 框架集:<frameset>:主要用来划分窗口的 框架页:<frame>:主要用来指定窗口 ...

  8. 浅谈对java中锁的理解

    在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...

  9. 设计模式的征途—1.单例(Singleton)模式

    单例模式属于创建型模式的一种,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛.创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修 ...

  10. linuxCentOs6前期简单且必要的设置

    1.修改主机名 Sudo vi /etc/sysconfig/network(需要重启) Hostname master (不需要重启,设置当前主机名为master) Hostname查看当前主机名 ...