`

Elasticsearch 多字段搜索 (二) - 最佳字段查询及其调优

阅读更多

原文链接:http://blog.csdn.net/dm_vincent/article/details/41820537

 

最佳字段(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查询具有的最佳匹配性质。

 

 

分享到:
评论

相关推荐

    elasticsearch-bulk-insert-plugin-8.2.0.0-342.zip

    Elasticsearch是一个强大的开源搜索引擎,常用于大数据分析和实时数据检索。Kettle,又称为Pentaho Data Integration(PDI),是一款数据集成工具,能够帮助用户进行数据抽取、转换和加载(ETL)操作。在Kettle中...

    最新版windows elasticsearch-7.8.0-windows-x86_64.zip

    在Windows环境下安装和使用Elasticsearch 7.8.0版本,用户可以享受到强大的搜索和分析功能,适用于日志分析、监控、数据存储等多个场景。 在下载的"elasticsearch-7.8.0-windows-x86_64.zip"压缩包中,包含了运行...

    elasticsearch-7.7.1-windows-x86_64.rar

    4. **文档型数据库**:Elasticsearch以文档为中心,每个文档属于一个特定的索引,并且可以包含多个字段。文档可以是JSON格式,便于处理结构化和半结构化数据。 5. **自动分词**:Elasticsearch内置了多种分词器,如...

    最新版windows elasticsearch-8.1.2-windows-x86_64.zip

    11. **性能调优**:为了优化Elasticsearch的性能,用户需要关注硬件配置(如足够的内存、SSD存储)、索引设置(如分词器、刷新间隔)、数据建模策略(如字段类型选择、映射配置)以及网络架构(如网络带宽和延迟)。...

    最新版Elasticsearch调优搜索速度.pdf

    本文将深入探讨影响Elasticsearch查询性能的因素,并提出一系列调优策略。 首先,Elasticsearch的软件生态包括Elastic Stack,由Elasticsearch、Logstash、Kibana、Beats等组件组成,提供了一个端到端的数据解决...

    elasticsearch-head-master-2020211.zip

    Elasticsearch Head是一款非常实用的Elasticsearch插件,它提供了直观的Web界面,使得用户可以方便地管理和监控Elasticsearch集群。这个压缩包“elasticsearch-head-master-2020211.zip”包含了2020年2月11日更新的...

    Elasticsearch调优实践

    **Elasticsearch调优实践** ...以上是Elasticsearch调优的一些核心点,实践中需要结合具体业务场景进行调整,以实现最佳性能。此外,了解Java编程基础对于深入理解ES内部机制和进行更细粒度的调优也很重要。

    elasticsearch-head-master-5.0.0版本.zip

    Elasticsearch-Head-Master-5.0.0版本是一个专为Elasticsearch设计的开源可视化管理工具,它基于Node.js开发,提供了直观且友好的界面,帮助用户更轻松地管理和监控Elasticsearch集群。这款工具是开发者和管理员的...

    elasticsearch-6.8.0+elasticsearch-analysis-ik-6.8.0 .zip

    通过将 Elasticsearch 与 Java 和 Spring Boot 集成,可以快速构建高性能的搜索引擎应用,满足实时数据处理和复杂查询的需求。同时,Elasticsearch 的灵活性和扩展性使其成为现代大数据环境下的理想选择。

    最新版linux elasticsearch-8.6.2-linux-x86-64.tar.gz

    Elasticsearch 8.6.2 是一个高度可扩展的开源全文搜索引擎,广泛应用于数据分析、日志聚合、实时搜索和大数据处理等领域。它是基于 Lucene 库构建的,提供了分布式、多用户环境下的高可用性和高性能。在 Linux 平台...

    elasticsearch-analysis-ik-6.1.3.tar.gz

    二、Elasticsearch全文搜索 Elasticsearch的全文搜索主要依赖于倒排索引机制。在创建索引时,Elasticsearch会对每个文档的字段进行分词,生成词项(Term),然后建立词项到文档的映射,形成倒排索引。当用户输入查询...

    elasticsearch-analysis-ik-5.6.3.zip

    Elasticsearch(简称ES)作为一款高性能、分布式、全文搜索引擎,广泛应用于日志分析、实时数据分析等领域。然而,对于中文文档的处理,Elasticsearch原生的分词能力相对较弱,这就需要借助于专门的中文分词插件,如...

    elasticsearch-7.12.0-windows-x86_64.zip

    Elasticsearch 7.12.0 是一个高度可扩展的全文搜索引擎,广泛应用于数据分析、日志聚合和实时搜索场景。这款开源软件基于Java开发,是Lucene库的封装和扩展,提供了分布式、多用户环境下的高效数据存储、检索与分析...

    elasticsearch-head chrome插件安装包

    4. **搜索与分析**:提供查询编辑器,支持复杂的Elasticsearch查询语法,可以实时执行搜索并查看结果。 5. **映射可视化**:展示索引的字段结构和映射,便于理解数据的存储方式和检索规则。 6. **性能分析**:展示...

    Elasticsearch顶尖高手系列课程-核心知识篇+高手进阶篇(免费无加密)

    根据提供的文件信息,我们可以推断出这是一套关于Elasticsearch的学习资料,旨在帮助学习者掌握Elasticsearch的核心知识及进阶技巧。接下来,我们将基于这些信息,详细展开相关的知识点。 ### Elasticsearch简介 ...

    Elasticsearch原理解析与性能调优

    ### Elasticsearch原理解析与性能调优 #### 一、Elasticsearch概述 Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎,以其强大的搜索能力和灵活性而闻名。它能够快速地存储、搜索和分析大量的数据,并且...

    elasticsearch-the-definitive-guide-cn

    Elasticsearch(简称ES)是一个基于Lucene的分布式、实时的搜索与分析引擎,它提供了丰富的API接口,使得数据检索、分析和可视化变得简单高效。以下是对本书内容的详细概述: 1. **Elasticsearch简介**:Elastic...

Global site tag (gtag.js) - Google Analytics