1. 插入数据

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

2. 搜索

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

3. 结果

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

  理论上 2 的文档其实是我们需要的,但是搜索的结果不是。要理解原因,需要知道 bool 查询时如何计算得到其分值的:

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

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

score_1 = ( + ) *  /  =
score_2 = ( + ) * / =

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

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

4. 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": "",
"_score": 0.21509302,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
},
{
"_id": "",
"_score": 0.12713557,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
}
]
}

5. 最佳字段查询调优

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

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

查询语句:
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
]
}
}
}
得到的结果:
{
"hits": [
{
"_id": "",
"_score": 0.12713557,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
},
{
"_id": "",
"_score": 0.12713557,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
}
]
}

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

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

6. tie_breaker

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

查询语句:
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
],
"tie_breaker": 0.3
}
}
}
它会返回以下结果:
{
"hits": [
{
"_id": "",
"_score": 0.14757764,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
},
{
"_id": "",
"_score": 0.124275915,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
}
]
}

现在文档2 的分值比文档1 稍高一些。
  tie_breaker参数会让dis_max查询的行为更像是dis_max和bool的一种折中。它会通过下面的方式改变分值计算过程:

  1. 取得最佳匹配查询子句的_score。

  2. 将其它每个匹配的子句的分值乘以tie_breaker。

  3. 将以上得到的分值进行累加并规范化。

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

ElasticSearch 之 dis_max tie_break的应用的更多相关文章

  1. ElasticSearch query_string vs multi_match cross_fields query

    ElasticSearch query_string vs multi_match cross_fields query 本文记录以字段为中心的查询和以词为中心的查询这两种查询方式的区别以及在Elas ...

  2. Query DSL for elasticsearch Query

    Query DSL Query DSL (资料来自: http://www.elasticsearch.cn/guide/reference/query-dsl/) http://elasticsea ...

  3. elasticsearch的rest搜索--- 查询

    目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0   三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 四. 查询 1. 查询的官网的文档   ...

  4. ElasticSearch快速指南

    ElasticSearch是基于Apache Lucene的分布式搜索引擎, 提供面向文档的搜索服务. 安装ElasticSearch 文档 创建文档 访问文档 更新文档 删除文档 索引 分析器 类型 ...

  5. Apache Solr vs Elasticsearch

    http://solr-vs-elasticsearch.com/ Apache Solr vs Elasticsearch The Feature Smackdown API Feature Sol ...

  6. Elasticsearch: 权威指南 » 深入搜索 » 多字段搜索 » 多数字段 good

      跨字段实体搜索  » 多数字段编辑 全文搜索被称作是 召回率(Recall) 与 精确率(Precision) 的战场: 召回率 ——返回所有的相关文档:精确率 ——不返回无关文档.目的是在结果的 ...

  7. Elasticsearch学习笔记(十四)relevance score相关性评分的计算(1)

    一.多shard场景下relevance score不准确问题     1.问题描述:            多个shard下,如果每个shard包含指定搜索条件的document数量不均匀的情况下, ...

  8. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  9. elasticsearch基本概念与查询语法

    序言 后面有大量类似于mysql的sum, group by查询 elk === elk总体架构 https://www.elastic.co/cn/products Beat 基于go语言写的轻量型 ...

随机推荐

  1. [BUAA软工]第一次博客作业---阅读《构建之法》

    [BUAA软工]第一次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第1次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...

  2. Linux内核分析第七周总结

    第七章 可执行程序的装载 可执行程序的生成 可执行程序的生成: c语言代码--->经过编译器的预处理--->编译成汇编代码--->由汇编器编译成目标代码--->链接成可执行文件 ...

  3. 网络:OSPF理解

    OSPF(开放最短路径优先)协议使用Dijkstra算法,常见的版本有:OSPFv2.OSPFv3等.以下主要介绍OSPFv2,OSPFv3是面向IPv6的且不兼容IPv4. 1.工作过程: 1)每台 ...

  4. 5.1 四则运算单元测试j

    由于上个星期请假没上课,这个星期回来才知道作业,时间比较赶,个人能力又不足,作业质量不是很好 Calculator.java import java.util.Scanner; public clas ...

  5. 【转】进程同步之信号量机制(pv操作)及三个经典同步问题

    原文地址:http://blog.csdn.net/speedme/article/details/17597373 上篇博客中(进程同步之临界区域问题及Peterson算法),我们对临界区,临界资源 ...

  6. Mock.js的简易使用

    一:安装 npm install mockjs --save-dev 二:引入 在src目录下创建mock.js文件,输入以下代码: // 引入mockjs const Mock = require( ...

  7. JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客

    JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客https://blog.csdn.net/KooKing_L/article/details/79711379

  8. Atlas & mysql-proxy

    Atlas https://github.com/Qihoo360/Atlas https://github.com/Qihoo360/Atlas/wiki/Installing-Atlas Atla ...

  9. ecshop验证码图片无法显示终极解决办法

    ecshop验证码图片无法显示终极解决办法 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2014-06-06   客户在安装好ecshop之后所有前台的证码不显示,后 ...

  10. 命令行方式(SSH or powershell )远程windows server

    1. 使用ssh的方式远程登录window server 网上找到的方法大部分是freesshd 或者是Copsshd这样的工具 方式就是 下载安装文件,然后服务器端进行安装: 安装完成之后作为服务启 ...