[Elasticsearch] 全文搜索 (三) - match查询和bool查询的关系,提升查询子句

match查询是如何使用bool查询的

现在,你也许意识到了使用了match查询的多词查询只是简单地将生成的term查询包含在了一个bool查询中。通过默认的or操作符,每个term查询都以一个k语句被添加,所以至少一个should语句需要被匹配。以下两个查询是等价的:

{
    "match": { "title": "brown fox"}
}

{
  "bool": {
    "should": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }}
    ]
  }
}

使用and操作符时,所有的term查询都以must语句被添加,因此所有的查询都需要匹配。以下两个查询是等价的:

{
    "match": {
        "title": {
            "query":    "brown fox",
            "operator": "and"
        }
    }
}

{
  "bool": {
    "must": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }}
    ]
  }
}

如果指定了minimum_should_match参数,它会直接被传入到bool查询中,因此下面两个查询是等价的:

{
    "match": {
        "title": {
            "query":                "quick brown fox",
            "minimum_should_match": "75%"
        }
    }
}

{
  "bool": {
    "should": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }},
      { "term": { "title": "quick" }}
    ],
    "minimum_should_match": 2
  }
}

因为只有3个查询语句,minimum_should_match的值75%会被向下舍入到2。即至少两个should语句需要匹配。

当然,我们可以通过match查询来编写这类查询,但是理解match查询的内部工作原理能够让你根据需要来控制该过程。有些行为无法通过一个match查询完成,比如对部分查询词条给予更多的权重。在下一节中我们会看到一个例子。

提升查询子句(Boosting Query Clause)

当然,bool查询并不是只能合并简单的单词(One-word)match查询。它能够合并任何其它的查询,包括其它的bool查询。它通常被用来通过合并数个单独的查询的分值来调优每份文档的相关度_score

假设我们需要搜索和"full-text search"相关的文档,但是我们想要给予那些提到了"Elasticsearch"或者"Lucene"的文档更多权重。更多权重的意思是,对于提到了"Elasticsearch"或者"Lucene"的文档,它们的相关度_score会更高,即它们会出现在结果列表的前面。

一个简单的bool查询能够让我们表达较为复杂的逻辑:

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "content": {
                        "query":    "full text search",
                        "operator": "and"
                    }
                }
            },
            "should": [
                { "match": { "content": "Elasticsearch" }},
                { "match": { "content": "Lucene"        }}
            ]
        }
    }
}
  1. content字段必须含有fulltextsearch这三个词条
  2. 如果content字段也含有了词条Elasticsearch或者Lucene,那么该文档会有一个较高的_score

should查询子句的匹配数量越多,那么文档的相关度就越高。目前为止还不错。

但是如果我们想给含有Lucene的文档多一些权重,同时给含有Elasticsearch的文档更多一些权重呢?

我们可以通过指定一个boost值来控制每个查询子句的相对权重,该值默认为1。一个大于1boost会增加该查询子句的相对权重。因此我们可以将上述查询重写如下:

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "content": {
                        "query":    "full text search",
                        "operator": "and"
                    }
                }
            },
            "should": [
                { "match": {
                    "content": {
                        "query": "Elasticsearch",
                        "boost": 3
                    }
                }},
                { "match": {
                    "content": {
                        "query": "Lucene",
                        "boost": 2
                    }
                }}
            ]
        }
    }
}

NOTE

boost参数被用来增加一个子句的相对权重(当boost大于1时),或者减小相对权重(当boost介于01时),但是增加或者减小不是线性的。换言之,boost设为2并不会让最终的_score加倍。

相反,新的_score会在适用了boost后被归一化(Normalized)。每种查询都有自己的归一化算法(Normalization
Algorithm),算法的细节超出了本书的讨论范围。但是能够说一个高的boost值会产生一个高的_score

如果你在实现你自己的不基于TF/IDF的相关度分值模型并且你需要对提升过程拥有更多的控制,你可以使用function_score查询,它不通过归一化步骤对文档的boost进行操作。

在下一章中,我们会介绍其它的用于合并查询的方法,多字段查询(Multifield Search)。但是,首先让我们看看查询的另一个重要特定:文本分析(Text
Analysis)。

时间: 2024-08-29 01:33:54

[Elasticsearch] 全文搜索 (三) - match查询和bool查询的关系,提升查询子句的相关文章

[Elasticsearch] 全文搜索 (一) - 基础概念和match查询

全文搜索(Full Text Search) 现在我们已经讨论了搜索结构化数据的一些简单用例,是时候开始探索全文搜索了 - 如何在全文字段中搜索来找到最相关的文档. 对于全文搜索而言,最重要的两个方面是: 相关度(Relevance) 查询的结果按照它们对查询本身的相关度进行排序的能力,相关度可以通过TF/IDF,参见什么是相关度,地理位置的邻近程度(Proximity to a Geo-location),模糊相似性(Fuzzy Similarity)或者其它算法进行计算. 解析(Analys

[Elasticsearch] 全文搜索 (二) - 多词查询及查询的合并

多词查询(Multi-word Queries) 如果我们一次只能搜索一个词,那么全文搜索就会显得相当不灵活.幸运的是,通过match查询来实现多词查询也同样简单: GET /my_index/my_type/_search { "query": { "match": { "title": "BROWN DOG!" } } } 以上的查询会返回所有的四份文档: { "hits": [ { "_id

Elasticsearch 全文搜索

1,匹配查询(match) match查询主要的应用场景是进行全文搜索: // 1,初始化数据 DELETE /my_index PUT /my_index { "settings": { "number_of_shards": 1 }} POST /my_index/my_type/_bulk { "index": { "_id": 1 }} { "title": "The quick brow

[Elasticsearch] 全文搜索 (四) - 控制分析及相关度

控制分析(Controlling Analysis) 查询只能摘到真实存在于倒排索引(Inverted Index)中的词条(Term),因此确保相同的分析过程会被适用于文档的索引阶段和搜索阶段的查询字符串是很重要的,这样才能够让查询中的词条能够和倒排索引中的词条匹配. 尽管我们说的是文档(Document),解析器(Analyzer)是因字段而异的(Determined per Field).每个字段都能够拥有一个不同的解析器,通过为该字段配置一个特定的解析器或者通过依赖类型(Type),索引

Elasticsearch 全文搜索和keyword search字段的mapping定义

在ES5.0之前我们对于需要keyword search的字段都是这样定义的: { "field name":{ "type": "string", "index": "not_analyzed" } } 全文检索: { "field name":{ "type": "string" } } ES 5+: keyword search: { &qu

[Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段

multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据"一节中提到的几种类型相同:best_fields,most_fields以及cross_fields. 默认情况下,该查询以best_fields类型执行,它会为每个字段生成一个match查询,然后将这些查询包含在一个dis_max查询中.下面的dis_max查询: { "dis_max

[Elasticsearch] 部分匹配 (三) - 查询期间的即时搜索

本章翻译自Elasticsearch官方指南的Partial Matching一章. 查询期间的即时搜索(Query-time Search-as-you-type) 现在让我们来看看前缀匹配能够如何帮助全文搜索.用户已经习惯于在完成输入之前就看到搜索结果了 - 这被称为即时搜索(Instant Search, 或者Search-as-you-type).这不仅让用户能够在更短的时间内看到搜索结果,也能够引导他们得到真实存在于我们的索引中的结果. 比如,如果用户输入了johnnie walker

ElasticSearch基础3:全文搜索

全文搜索 所有查询会或多或少的执行相关度计算,但不是所有查询都有分析阶段.和一些特殊的完全不会对文本进行操作的查询(如 bool 或 function_score )不同,文本查询可以划分成两大家族: 基于词项的查询 如 term 或 fuzzy 这样的底层查询不需要分析阶段,它们对单个词项进行操作.用 term 查询词项 Foo 只要在倒排索引中查找 准确词项 ,并且用 TF/IDF 算法为每个包含该词项的文档计算相关度评分 _score .记住 term 查询只对倒排索引的词项精确匹配,这点

ElasticSearch结构化搜索和全文搜索

https://segmentfault.com/a/1190000019753737?utm_source=tag-newest 1.结构化搜索 1.1 精确值查找 过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存.请尽可能多的使用过滤式查询. term 查询会查找我们指定的精确值.作为其本身, term 查询是简单的.它接受一个字段名以及我们希望查找的数值:{ "term" : { "price" : 20 } }