最佳字段(Best Fields)

假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样:

PUT /my_index/my_type/1
{"title": "Quick brown rabbits","body":  "Brown rabbits are commonly seen."
}PUT /my_index/my_type/2
{"title": "Keeping pets healthy","body":  "My quick brown fox eats rabbits on a regular basis."
}

用户输入了"Brown fox",然后按下了搜索键。我们无法预先知道用户搜索的词条会出现在博文的title或者body字段中,但是用户是在搜索和他输入的单词相关的内容。以上的两份文档中,文档2似乎匹配的更好一些,因为它包含了用户寻找的两个单词。

让我们运行下面的bool查询:

{"query": {"bool": {"should": [{ "match": { "title": "Brown fox" }},{ "match": { "body":  "Brown fox" }}]}}
}

然后我们发现文档1的分值更高:

{"hits": [{"_id":      "1","_score":   0.14809652,"_source": {"title": "Quick brown rabbits","body":  "Brown rabbits are commonly seen."}},{"_id":      "2","_score":   0.09256032,"_source": {"title": "Keeping pets healthy","body":  "My quick brown fox eats rabbits on a regular basis."}}]
}

要理解原因,想想bool查询是如何计算得到其分值的:

  1. 运行should子句中的两个查询
  2. 相加查询返回的分值
  3. 将相加得到的分值乘以匹配的查询子句的数量
  4. 除以总的查询子句的数量

文档1在两个字段中都包含了brown,因此两个match查询都匹配成功并拥有了一个分值。文档2在body字段中包含了brown以及fox,但是在title字段中没有出现任何搜索的单词。因此对body字段查询得到的高分加上对title字段查询得到的零分,然后在乘以匹配的查询子句数量1,最后除以总的查询子句数量2,导致整体分值比文档1的低。

在这个例子中,titlebody字段是互相竞争的。我们想要找到一个最佳匹配(Best-matching)的字段。

如果我们不是合并来自每个字段的分值,而是使用最佳匹配字段的分值作为整个查询的整体分值呢?这就会让包含有我们寻找的两个单词的字段有更高的权重,而不是在不同的字段中重复出现的相同单词。

dis_max查询

相比使用bool查询,我们可以使用dis_max查询(Disjuction Max Query)。Disjuction的意思"OR"(而Conjunction的意思是"AND"),因此Disjuction Max Query的意思就是返回匹配了任何查询的文档,并且分值是产生了最佳匹配的查询所对应的分值:

{"query": {"dis_max": {"queries": [{ "match": { "title": "Brown fox" }},{ "match": { "body":  "Brown fox" }}]}}
}

它会产生我们期望的结果:

{"hits": [{"_id":      "2","_score":   0.21509302,"_source": {"title": "Keeping pets healthy","body":  "My quick brown fox eats rabbits on a regular basis."}},{"_id":      "1","_score":   0.12713557,"_source": {"title": "Quick brown rabbits","body":  "Brown rabbits are commonly seen."}}]
}

最佳字段查询的调优

如果用户搜索的是"quick pets",那么会发生什么呢?两份文档都包含了单词quick,但是只有文档2包含了单词pets。两份文档都没能在一个字段中同时包含搜索的两个单词。

一个像下面那样的简单dis_max查询会选择出拥有最佳匹配字段的查询子句,而忽略其他的查询子句:

{"query": {"dis_max": {"queries": [{ "match": { "title": "Quick pets" }},{ "match": { "body":  "Quick pets" }}]}}
}

{"hits": [{"_id": "1","_score": 0.12713557, "_source": {"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen."}},{"_id": "2","_score": 0.12713557, "_source": {"title": "Keeping pets healthy","body": "My quick brown fox eats rabbits on a regular basis."}}]
}

可以发现,两份文档的分值是一模一样的。

我们期望的是同时匹配了title字段和body字段的文档能够拥有更高的排名,但是结果并非如此。需要记住:dis_max查询只是简单的使用最佳匹配查询子句得到的_score

tie_breaker

但是,将其它匹配的查询子句考虑进来也是可能的。通过指定tie_breaker参数:

{"query": {"dis_max": {"queries": [{ "match": { "title": "Quick pets" }},{ "match": { "body":  "Quick pets" }}],"tie_breaker": 0.3}}
}

它会返回以下结果:

{"hits": [{"_id": "2","_score": 0.14757764, "_source": {"title": "Keeping pets healthy","body": "My quick brown fox eats rabbits on a regular basis."}},{"_id": "1","_score": 0.124275915, "_source": {"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen."}}]
}

现在文档2的分值比文档1稍高一些。

tie_breaker参数会让dis_max查询的行为更像是dis_maxbool的一种折中。它会通过下面的方式改变分值计算过程:

  1. 取得最佳匹配查询子句的_score
  2. 将其它每个匹配的子句的分值乘以tie_breaker
  3. 将以上得到的分值进行累加并规范化。

通过tie_breaker参数,所有匹配的子句都会起作用,只不过最佳匹配子句的作用更大。

NOTE

tie_breaker的取值范围是01之间的浮点数,取0时即为仅使用最佳匹配子句(译注:和不使用tie_breaker参数的dis_max查询效果相同),取1则会将所有匹配的子句一视同仁。它的确切值需要根据你的数据和查询进行调整,但是一个合理的值会靠近0,(比如,0.1 -0.4),来确保不会压倒dis_max查询具有的最佳匹配性质。

from:http://blog.csdn.net/dm_vincent/article/details/41820537

[Elasticsearch2.x] 多字段搜索 (二) - 最佳字段查询及其调优 译相关推荐

  1. 系统学习深度学习(二十五)--CNN调优总结

    资料来自网上,略有删改. 1.针对CNN优化的总结:Systematic evaluation of CNN advances on the ImageNet 使用没有 batchnorm 的 ELU ...

  2. Mysql 参数最佳实践_MySQL参数调优最佳实践

    前言 很多时候,RDS用户经常会问如何调优RDS MySQL的参数,为了回答这个问题,写一篇blog来进行解释: 哪一些参数不能修改,那一些参数可以修改: 这些提供修改的参数是不是已经是最佳设置,如何 ...

  3. hive表指定分区字段搜索_Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件...

    首先说一下,这里解决的问题应用场景: sparksql处理Hive表数据时,判断加载的是否是分区表,以及分区表的字段有哪些?再进一步限制查询分区表必须指定分区? 这里涉及到两种情况:select SQ ...

  4. 【大数据之Hadoop】二十五、生产调优-HDFS核心参数

    1 NameNode内存生产配置 Hadoop3.x系列的NameNode内存是动态分配的,可以用jmap -heap 进程号 查看分配的内存. 在hadoop102中NameNode和DataNod ...

  5. PostgreSQL 实时高效搜索 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询...

    标签 PostgreSQL , 搜索引擎 , GIN , ranking , high light , 全文检索 , 模糊查询 , 正则查询 , 相似查询 , ADHOC查询 背景 字符串搜索是非常常 ...

  6. [Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 译

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...

  7. Elastic search常用分词 和 多字段搜索优化

    分词器 ES的分词器把文本解析为一个一个的词,写入倒排索引中 filter过滤器 lemmagen 词性还原 stop 停顿词 shingle 临近词n个作为一组查询 analyzer分词器 stan ...

  8. java 多字段搜索_Elasticsearch系列---多字段搜索

    ### 概要 本篇介绍一下multi_match的best_fields.most_fields和cross_fields三种语法的场景和简单示例. ### 最佳字段 bool查询采取"mo ...

  9. elasticsearch优化之多字段搜索multi_match查询

    1 首先说下multi_match多字段匹配的三种类型,分别是best_fields(最佳字段) . most_fields(多数字段) 和 cross_fields(跨字段) 2 best_fiel ...

  10. ElasticSearch之搜索结果返回字段长度问题

    有时候,前端页面空间较小,ES搜索结果返回字段过大,放不下,或者放得下,但是很丑,所以我们如何对大字段进行处理呢? 两种方法: 方法一:(非常low,建议直接略过看方法二) 对es搜索结果进行截取判断 ...

最新文章

  1. MyBatis的使用
  2. 2014年国内最热门的.NET开源平台
  3. R语言使用ggplot2包和maps包可视化美国地图、使用北美犯罪率数据为不同区域的地图渲染(颜色深浅区分犯罪率高低、US map colored by violent crime rates)
  4. mysql datetime转date_一个MySQL时间戳精度引发的血案
  5. PHP 实现冒泡排序
  6. 获取清空textarea的文字内容_运用|你会做 词云图(文字云) 吗?
  7. mxnet深度学习(KVS)
  8. 公布 | 中国图象图形学学会首批Fellow名单公布
  9. 在linux 下编译c程序时“ error:dereferencing pointer to incomplete type”的问题
  10. 2怎么升级固件_西门子PLC固件升级,S71200 固件升级方法
  11. 图像形状特征(八)--SC形状上下文
  12. 【干货】跨端体验度量的思考与实现(含直播回放)
  13. 【神经网络】激活函数的作用及常用激活函数
  14. 仿win7 aero_在Windows 7中获取Aero风格的经典开始菜单
  15. XenServer 7.0基础命令及故障处理办法
  16. 什么是云服务举例说明_什么是云服务(什么是云服务举例说明)
  17. 无人值守称重系统解决方案,加快企业数字化发展
  18. 网站规划通识:原型图绘制的一些注意事项
  19. c语言程序设计中植树问题,植树问题 (3).doc
  20. 常用符号计算机输入法,玩电脑必备:一些特殊符号的组合输入法

热门文章

  1. 关于水晶报表打包的一些注意的地方!
  2. Unicode 字符集下不同类型数据下的转换
  3. 使用Mac通知中心,生活讯息一眼看尽
  4. TeamViewer 远程设备的画面黑屏怎么办?
  5. Z-score标准化[转载]
  6. 《solidity学习笔记》chapter 2-solidity基础知识
  7. Lync Server 2013 实战系列之二:标准版-前期准备
  8. SQL AZURE数据库创建,云计算体验之一
  9. VMware Fusion中使用迅雷的问题
  10. 雅虎想卖个好价钱 竞购方却抱怨它遮遮掩掩