顾名思义,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. 推荐一本书:清华出版的《Modbus软件开发实战指南》

    前言: 最近在研究Modbus开发,如果只是简单的了解了一些modbus基础知识,但是不够系统和全面. 其实,modbus虽然比较简单,但是如果不注意有很多坑,特别是寄存器的位数,大小端处理,浮点数, ...

  2. 1613: [Usaco2007 Jan]Running贝茜的晨练计划

    1613: [Usaco2007 Jan]Running贝茜的晨练计划 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1252  Solved: 609 ...

  3. 同步 VS 异步

    同步请求资源 请求msdn上的一个页面计算页面大小 static void Main(string[] args) { string url = "https://docs.microsof ...

  4. Java的Date和Time入门教程

    本文是一篇翻译文章,已取得原作者授权,原文地址是http://tutorials.jenkov.com/java-date-time/index.html Java语言的JDK中关于日期和时间的API ...

  5. php文件管理与基础功能的实现

    文件的基本操作 先来看一下PHP文件基础操作,请看强大注释 <body> <?php var_dump(filetype("./img/11.png")); // ...

  6. 浅谈隐语义模型和非负矩阵分解NMF

    本文从基础介绍隐语义模型和NMF. 隐语义模型 ”隐语义模型“常常在推荐系统和文本分类中遇到,最初来源于IR领域的LSA(Latent Semantic Analysis),举两个case加快理解. ...

  7. Gson和Json

    一下内容为复制别人的: Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. j ...

  8. 【VB超简单入门】五、基本输出输入

    之前讲了VB IDE的基本操作和概念,接下来要开始将VB语言的编程了. 程序最重要的部分是输出和输入,输入数据,经过计算机处理,再输出结果.本文将介绍两种最基本的输出输入方法,分别是Print.Msg ...

  9. 机器学习 - pycharm, pyspark, spark集成篇

    AS WE ALL KNOW,学机器学习的一般都是从python+sklearn开始学,适用于数据量不大的场景(这里就别计较“不大”具体指标是啥了,哈哈) 数据量大了,就需要用到其他技术了,如:spa ...

  10. Oracle存储过程的调用和执行

    1.什么是存储过程: 用于在数据库中完成特定的操作或者任务.是一个PLSQL程序块,可以永久的保存在数据库中以供其他程序调用. 2.无参存储过程的使用: Normal 0 7.8 磅 0 2 fals ...