`

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

阅读更多

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

 

 

multi_match查询

 

 

multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询。

NOTE

存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据"一节中提到的几种类型相同:best_fieldsmost_fields以及cross_fields

默认情况下,该查询以best_fields类型执行,它会为每个字段生成一个match查询,然后将这些查询包含在一个dis_max查询中。下面的dis_max查询:

{
  "dis_max": {
    "queries":  [
      {
        "match": {
          "title": {
            "query": "Quick brown fox",
            "minimum_should_match": "30%"
          }
        }
      },
      {
        "match": {
          "body": {
            "query": "Quick brown fox",
            "minimum_should_match": "30%"
          }
        }
      },
    ],
    "tie_breaker": 0.3
  }
}

可以通过multi_match简单地重写如下:

{
    "multi_match": {
        "query":                "Quick brown fox",
        "type":                 "best_fields", 
        "fields":               [ "title", "body" ],
        "tie_breaker":          0.3,
        "minimum_should_match": "30%" 
    }
}

注意到以上的type属性为best_fields。 minimum_should_matchoperator参数会被传入到生成的match查询中。

在字段名中使用通配符

字段名可以通过通配符指定:任何匹配了通配符的字段都会被包含在搜索中。你可以通过下面的查询来匹配book_titlechapter_title以及section_title字段:

{
    "multi_match": {
        "query":  "Quick brown fox",
        "fields": "*_title"
    }
}

提升个别字段

个别字段可以通过caret语法(^)进行提升:仅需要在字段名后添加^boost,其中的boost是一个浮点数:

{
    "multi_match": {
        "query":  "Quick brown fox",
        "fields": [ "*_title", "chapter_title^2" ] 
    }
}

chapter_title字段的boost值为2,而book_titlesection_title字段的boost值为默认的1


 

 

多数字段(Most Fields)

 

全文搜索是一场召回率(Recall) - 返回所有相关的文档,以及准确率(Precision) - 不返回无关文档,之间的战斗。目标是在结果的第一页给用户呈现最相关的文档。

为了提高召回率,我们会广撒网 - 不仅包括精确匹配了用户搜索词条的文档,还包括了那些我们认为和查询相关的文档。如果一个用户搜索了"quick brown fox",一份含有fast foxes的文档也可以作为一个合理的返回结果。

如果我们拥有的相关文档仅仅是含有fast foxes的文档,那么它会出现在结果列表的顶部。但是如果我们有100份含有quick brown fox的文档,那么含有fast foxes的文档的相关性就会变低,我们希望它出现在结果列表的后面。在包含了许多可能的匹配后,我们需要确保相关度高的文档出现在顶部。

一个用来调优全文搜索相关性的常用技术是将同样的文本以多种方式索引,每一种索引方式都提供了不同相关度的信号(Signal)。主要字段(Main field)中含有的词条的形式是最宽泛的(Broadest-matching),用来尽可能多的匹配文档。比如,我们可以这样做:

  • 使用一个词干提取器来将jumps,jumping和jumped索引成它们的词根:jump。然后当用户搜索的是jumped时,我们仍然能够匹配含有jumping的文档。
  • 包含同义词,比如jump,leap和hop。
  • 移除变音符号或者声调符号:比如,ésta,está和esta都会以esta被索引。

但是,如果我们有两份文档,其中之一含有jumped,而另一份含有jumping,那么用户会希望第一份文档的排序会靠前,因为它含有用户输入的精确值。

我们可以通过将相同的文本索引到其它字段来提供更加精确的匹配。一个字段可以包含未被提取词干的版本,另一个则是含有变音符号的原始单词,然后第三个使用了shingles,用来提供和单词邻近度相关的信息。这些其它字段扮演的角色就是信号(Signals),它们用来增加每个匹配文档的相关度分值。能够匹配的字段越多,相关度就越高。

如果一份文档能够匹配具有最宽泛形式的主要字段(Main field),那么它就会被包含到结果列表中。如果它同时也匹配了信号字段,它会得到一些额外的分值用来将它移动到结果列表的前面。

我们会在本书的后面讨论同义词,单词邻近度,部分匹配以及其他可能的信号,但是我们会使用提取了词干和未提取词干的字段的简单例子来解释这个技术。

多字段映射(Multifield Mapping)

第一件事就是将我们的字段索引两次:一次是提取了词干的形式,一次是未提取词干的形式。为了实现它,我们会使用多字段(Multifields),在字符串排序和多字段中我们介绍过:

DELETE /my_index

PUT /my_index
{
    "settings": { "number_of_shards": 1 }, 
    "mappings": {
        "my_type": {
            "properties": {
                "title": { 
                    "type":     "string",
                    "analyzer": "english",
                    "fields": {
                        "std":   { 
                            "type":     "string",
                            "analyzer": "standard"
                        }
                    }
                }
            }
        }
    }
}

title字段使用了english解析器进行词干提取。 title.std字段则使用的是standard解析器,因此它没有进行词干提取。

下一步,我们会索引一些文档:

PUT /my_index/my_type/1
{ "title": "My rabbit jumps" }

PUT /my_index/my_type/2
{ "title": "Jumping jack rabbits" }

以下是一个简单的针对title字段的match查询,它查询jumping rabbits:

GET /my_index/_search
{
   "query": {
        "match": {
            "title": "jumping rabbits"
        }
    }
}

它会变成一个针对两个提干后的词条jump和rabbit的查询,这要得益于english解析器。两份文档的title字段都包含了以上两个词条,因此两份文档的分值是相同的:

{
  "hits": [
     {
        "_id": "1",
        "_score": 0.42039964,
        "_source": {
           "title": "My rabbit jumps"
        }
     },
     {
        "_id": "2",
        "_score": 0.42039964,
        "_source": {
           "title": "Jumping jack rabbits"
        }
     }
  ]
}

如果我们只查询title.std字段,那么只有文档2会匹配。但是,当我们查询两个字段并将它们的分值通过bool查询进行合并的话,两份文档都能够匹配(title字段也匹配了),而文档2的分值会更高一些(匹配了title.std字段):

GET /my_index/_search
{
   "query": {
        "multi_match": {
            "query":  "jumping rabbits",
            "type":   "most_fields", 
            "fields": [ "title", "title.std" ]
        }
    }
}

在上述查询中,由于我们想合并所有匹配字段的分值,因此使用的类型为most_fields。这会让multi_match查询将针对两个字段的查询子句包含在一个bool查询中,而不是包含在一个dis_max查询中。

{
  "hits": [
     {
        "_id": "2",
        "_score": 0.8226396, 
        "_source": {
           "title": "Jumping jack rabbits"
        }
     },
     {
        "_id": "1",
        "_score": 0.10741998, 
        "_source": {
           "title": "My rabbit jumps"
        }
     }
  ]
}

此时,文档2的分值比文档1的高许多。

我们使用了拥有宽泛形式的title字段来匹配尽可能多的文档 - 来增加召回率(Recall),同时也使用了title.std字段作为信号来让最相关的文档能够拥有更靠前的排序(译注:增加了准确率(Precision))。

每个字段对最终分值的贡献可以通过指定boost值进行控制。比如,我们可以提升title字段来让该字段更加重要,这也减小了其它信号字段的影响:

GET /my_index/_search
{
   "query": {
        "multi_match": {
            "query":       "jumping rabbits",
            "type":        "most_fields",
            "fields":      [ "title^10", "title.std" ] 
        }
    }
}
分享到:
评论

相关推荐

    elasticsearch02

    因此你根据三个字段搜索,和根据all字段搜索效果当然一样了。但是,搜索字段越多,对查询性能影响越大,因此建议采用copy_to,然后单字段查询的方式。 1.2.4.总结 match和multi_match的区别是什么? * match:...

    springBoot动态操作Elasticsearch组件

    要实现所有属性字段的模糊查询,我们可以利用Elasticsearch的`multi_match`查询。创建一个自定义查询方法,如`@Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"*\"], \"type\": \"most_fields\"}}")...

    Demo.zip_DEMO_YOG_查询es

    在IT行业中, Elasticsearch(ES)是一种广泛使用的分布式搜索引擎,它基于Lucene库,以其高效、可扩展和实时的搜索能力而闻名。在这个名为"Demo.zip_DEMO_YOG_查询es"的压缩包文件中,我们可以推测它包含了演示如何...

    elasticsearch笔记1

    在Elasticsearch中,查询是检索数据的核心操作,本笔记主要介绍了多种查询方式,帮助我们更有效地从索引中获取匹配的数据。 1. **全部查询**: 使用`match_all`查询可以返回索引中的所有文档。在示例中,GET请求`...

    人工智能-项目实践-搜索引擎-SpringBoot+ElasticSearch全文搜索引擎

    6. **全文搜索实现**:利用Elasticsearch的查询DSL(Domain Specific Language)进行复杂查询,例如使用match、multi_match、bool、nested等查询类型,实现模糊搜索、短语搜索、多字段搜索等功能。 7. **分页和排序...

    搜索引擎学习 方便查找!

    - `multi_match` 查询:同时针对多个字段。 ```json { "query": { "multi_match": { "query": "TEXT", "fields": ["FIELD1", "FIELD2"] } } } ``` - **示例**:假设我们有一个包含品牌、名称、业务等...

    elasticsearch中term与match的区别讲解

    除了基本的Match查询,Elasticsearch还提供了其他变体,如Match Phrase查询(Match Phrase Query),用于执行短语匹配,以及Multi Match查询(Multi Match Query),可以在多个字段中同时执行Match查询,提高搜索的...

    ElasticSearch.pdf

    - **match查询**:match_all返回所有文档,match查询特定字段,fuzzy模糊匹配,multi_match多字段查询。 - **复合查询**:bool查询组合多种条件,filter过滤文档。 5. **聚合分析**: - Elasticsearch支持丰富的...

    Elasticsearch-sgg

    Elasticsearch(简称ES)是一款开源的全文搜索引擎,以其高效、可扩展和易用性在大数据分析和实时搜索领域广泛应用。它基于Lucene库构建,但提供了更高级别的分布式、RESTful风格的搜索和数据分析引擎。本资料将带你...

    elasticsearch数据库下载、配置、使用案例PPT模板

    ### Elasticsearch...综上所述,Elasticsearch是一款强大的搜索引擎和数据分析平台,适用于多种应用场景。通过本文详细介绍的下载、配置、使用以及优化方法,可以帮助开发者更好地利用Elasticsearch解决实际问题。

    Python-ElasticSearch搜索查询的讲解

    ### Python-ElasticSearch搜索查询详解 #### 引言 Elasticsearch作为一个强大的分布式搜索和分析引擎,被广泛应用于各类应用场景中,例如日志数据分析、实时应用程序监控以及网站搜索等。其核心特性在于能够处理...

    分布式搜索 ppt说明资料

    而`multi_match_query`则可以在多个字段中同时进行搜索,增强了查询的灵活性,但可能会降低查询性能,因为它涉及更多的字段扫描。 精准查询主要针对keyword、数值、日期、布尔等类型的字段,如`term`查询根据精确的...

    Springboot集成Elasticsearch+京东搜索实战代码

    可以利用Elasticsearch的`multi_match`查询、`nested`字段处理关联数据、`sort`进行排序,以及`bool`查询进行条件过滤。 ```java // 示例查询:根据关键词搜索商品,按价格降序排列 BoolQueryBuilder boolQuery = ...

    ElasticSearch可扩展的开源弹性搜索解决方案.docx

    - **查询DSL**:将多个简单的查询封装为一个 JSON 对象发送给 ElasticSearch,便于执行复杂的搜索操作。 - **示例查询**: ```bash curl -X GET 'localhost:9200/library/book/_search?q=title:crime&pretty=true...

    ES高手进阶篇part1

    《ES高手进阶篇part1》是一系列关于Elasticsearch(ES)高级应用的教程,主要涵盖了一系列深度探秘搜索技术和结构化搜索方法。通过这些视频教程,学习者可以深入理解ES的高级特性,提高在实际项目中的搜索引擎优化...

    es的简单查询和聚合查询用法说明

    Elasticsearch(简称ES)是基于Lucene的分布式搜索引擎,广泛应用于日志分析、全文检索、实时数据分析等场景。在本教程中,我们将深入探讨Elasticsearch的简单查询和聚合查询,帮助你更好地理解和应用这一强大的工具...

    ElasticSearch server

    - **Multi-Match Query**:在多个字段中同时搜索。 - **高级查询** - **Query String Query**:使用 Lucene 查询语法进行搜索。 - **Search Type**:控制搜索执行方式。 - **Execution Preference**:指定搜索...

    分布式搜索引擎02.pdf

    在Elasticsearch(ES)这个流行的分布式搜索引擎中,查询操作是其核心功能之一,主要通过领域特定语言(DSL)来实现。 DSL查询在Elasticsearch中以JSON格式进行,支持多种查询类型,包括查询所有、全文检索、精确...

    Ruby-elasticsearchrubyRuby集成Elasticsearch

    除了基本操作,还可以进行更复杂的操作,如聚合(Aggregations)、脚本字段(Script Fields)、多搜索(Multi Search)等。例如,使用过滤器聚合计算某个字段的平均值: ```ruby aggregation = { avg_price: { ...

    Jakes - 基于ES的音乐搜索引擎

    - **multi_match query**:支持对多个字段进行全文搜索。 - **bool query**:组合多种条件进行精确匹配。 - **function_score query**:为文档打分,按分数排序结果。 - **nested query**:处理嵌套文档结构。 ####...

Global site tag (gtag.js) - Google Analytics