带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(14)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(14)


《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.3.全文搜索/精确搜索(13) https://developer.aliyun.com/article/1229926



4.5 multi_match

 

multi_match 查询,即多字段查询,区别于 term 和 match 对单一字段的查询,multi_match 扩展了搜索的范围。使用方式如下:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

在 fields 内容中,使用者可以指定多个字段查询。

 

其中:

 

1、可以使用 * 代替字符进行 wildcard 匹配。比如:"fields": [ "title", "*_name" ] 代表

fisrt_name 和 last_name。注意,在使用 wildcard 匹配时,匹配到的字段数如果过多,则最大能查询的条件数受 indices.query.bool.max_clause_count 的限制,默认是1024。

2、可以使用 ^ 符号进行字段查询时的加权。比如:"fields" : [ "subject^3", "message" ]其中 subject 字段在算分时时 message 字段的三倍。

在多字段查询时,字段和被查询词项的关系主要有:best_fields/most_fields/cross_fields/phrase/phrase_prefix/bool_prefix,这六种关联方式。

 

best_fields

 

默认的查询方式,返回的文档排序按照其中某个字段得分最高的排在前面,这是一种单字段匹配优先的查询方式。

 

比如:查询 "brown fox",单个字段中出现 "brown fox" 的文档要比两个字段分别出现 brown 和 fox 的文档得分高。

 

best_fields 的方式是产生一个多 match 查询,然后将多个字段查询条件进行 dis_max 查询,将单字段得分高的排在前面

 

类似于这样的查询:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "brown fox",
      "type":       "best_fields",
      "fields":     [ "subject", "message" ],
      "tie_breaker": 0.3
    }
  }
}

执行起来是这样的:


GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        { "match": { "subject": "brown fox" }},
        { "match": { "message": "brown fox" }}
      ],
      "tie_breaker": 0.3
    }
  }
}

在查询中算分过程如下如下:

 

1、取字段算分中的最高分

2、加上 tie_breaker 乘以其它匹配字段的 _score

 

most_fields

 

这种查询类型,返回的文档排序按照被查询字段匹配的越多排在越前面。

 

most_fields 查询方法如下:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown fox",
      "type":       "most_fields",
      "fields":     [ "title", "title.original", "title.shingles" ]
}
  }
}

等同于:


GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":          "quick brown fox" }},
        { "match": { "title.original": "quick brown fox" }},
        { "match": { "title.shingles": "quick brown fox" }}
      ]
    }
  }
}

最后算分将每个 match 子句的得分加在一起,然后除以 match 子句的数量。

 

注意:operator 和 minimum_should_match 条件是对 best_fields 和 most_fields 查询产生的每个查询子句的查询关系,而不会对查询字段进行 operator 的控制。

 

比如:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}

执行的效果则是 (+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)的效果,即每个 match 查询的 and 关系。

 

phrase 和 phrase_prefix

 

在结果排序上的逻辑与 best_fields 一致,只是在查询方式上以 match_phrase 或者 match_phrase_prefix 的方式进行。

 

即,下面的查询:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown f",
      "type":       "phrase_prefix",
      "fields":     [ "subject", "message" ]
    }
  }
}

与这个查询是一样的:

GET /_search
{
  "query": {
"dis_max": {
      "queries": [
        { "match_phrase_prefix": { "subject": "quick brown f" }},
        { "match_phrase_prefix": { "message": "quick brown f" }}
      ]
    }
  }
}


bool_prefix

 

在结果排序的逻辑与 most_fields 一致,但是查询使用的是 match_bool_prefix 而不是 match。即,下面的查询:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown f",
      "type":       "bool_prefix",
      "fields":     [ "subject", "message" ]
    }
  }
}

与这个查询类似:


GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match_phrase_prefix": { "subject": "quick brown f" }},
        { "match_phrase_prefix": { "message": "quick brown f" }} 
      ]
    }
  }
}

最后算分将每个 match 子句的得分加在一起,然后除以 match 子句的数量。

 

cross_fields

 

将被查询的字段是为一个大字段,进行统一的分词并按照要求进行查询。

 

cross_fields 主要可以在查询时指定字段之间的关系,可以对词项在字段间的查询有更多的操控性,而不是统一默认的关系,甚至每个字段也并不一定需要满足才能返回文档。

 

比如下面的查询:


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and"
    }
  }
}

查询逻辑更像是这样: (first_name:will OR last_name:will) + (first_name:smith OR last_name:smith),而两个字段并不一定都需要匹配 will 或者 smith,两个字段中有一个能匹配上文档就可以返回。

由于在 TF/IDF 算法中,词频是一个重要的影响因素,因此 cross_fields 能有有效消除词频在不同字段中的差距,解决了 best_fields 的词频差问题。

 

注意,cross_fields 通常只对 boost 为 1 的短字符串字段有用。除此之外,索引算法中词频和长度标准化也会对分数产生影响,从而导致 term 统计数据的混合不再有意义。cross_fields在分词器的处理上,只会将分词器相同的字段分组查询,然后对分组进行最高分比较。

 

比如,first 和 last 字段是相同的分词器,而 first.simple 和 last.simple 使用的是相同的分词器。


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Jon",
      "type":       "cross_fields",
      "fields":     [
        "first", "first.simple",
        "last",  "last.simple"
      ]
    }
  }
}

那么查询逻辑是这样的:


GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "multi_match" : {
            "query":      "Jon",
            "type":       "cross_fields",
            "fields":     [ "first", "last" ] 
          }
        },
        {
          "multi_match" : {
            "query":      "Jon",
            "type":       "cross_fields",
            "fields":     [ "first.simple","last.simple" ]
          }
        }
      ]
    }
  }
}

关于 minimum_should_match:在多分词器分组的条件下,minimum_should_match 对分组的查询是对每个查询子项的统一化设置(即与 best_fields 一样的情况),所以有特殊的条件可以考虑分开重写。

 

注意:fuzziness 参数不可用于 cross_fields、phrase和 phrase_prefix 类型。

 



《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.3.全文搜索/精确搜索(15) https://developer.aliyun.com/article/1229924

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(7)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(7)
|
自然语言处理
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(13)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(13)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(11)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(11)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(6)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(6)
|
索引
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(5)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(5)
104 0
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(12)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(12)
|
缓存 索引
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(4)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(4)
|
自然语言处理 API 索引
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(16)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(16)
116 0
|
JSON Apache 数据格式
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(8)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(8)
|
自然语言处理 API 索引
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(3)
带你读《Elastic Stack 实战手册》之34:——3.4.2.17.3.全文搜索/精确搜索(3)
106 0