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": },
"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/
{ "title": "My rabbit jumps" } PUT /my_index/my_type/
{ "title": "Jumping jack rabbits" }

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

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

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

 {
"hits": [
{
"_id": "",
"_score": 0.42039964,
"_source": {
"title": "My rabbit jumps"
}
},
{
"_id": "",
"_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": "",
"_score": 0.8226396,
"_source": {
"title": "Jumping jack rabbits"
}
},
{
"_id": "",
"_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" ]
}
}
}

from:http://blog.csdn.net/dm_vincent/article/details/41842691

[Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 <译>的更多相关文章

  1. [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段 <译>

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...

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

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...

  3. [Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段

    自定义_all字段 在元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引.尽管将所有字段的值作为一个字段进行索引并不是非常灵活.如果有一个自定义的_al ...

  4. Elasticsearch 全字段搜索_all,query_string查询,不进行分词

    最近在使用ELasitcsearch的时候,需要用到关键字搜索,因为是全字段搜索,就需要使用_all字段的query_string进行搜索. 但是在使用的时候,遇到问题了.我们的业务并不需要分词,我在 ...

  5. elasticsearch多字段搜索

    https://blog.csdn.net/Ricky110/article/details/78888711 多字段搜索多字符串查询boost 参数 “最佳” 值,较为简单的方式就是不断试错,比较合 ...

  6. [Elasticsearch2.x] 多字段搜索 (一) - 多个及单个查询字符串 <译>

    多字段搜索(Multifield Search) 本文翻译自官方指南的Multifield Search一章. 查询很少是只拥有一个match查询子句的查询.我们经常需要对一个或者多个字段使用相同或者 ...

  7. [Elasticsearch2.x] 多字段搜索 (二) - 最佳字段查询及其调优 <译>

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/ { "title": "Q ...

  8. [Elasticsearch] 多字段搜索 (五) - 以字段为中心的查询

    以字段为中心的查询(Field-centric Queries) 上述提到的三个问题都来源于most_fields是以字段为中心(Field-centric),而不是以词条为中心(Term-centr ...

  9. [Elasticsearch] 多字段搜索 (一) - 多个及单个查询字符串

    多字段搜索(Multifield Search) 本文翻译自官方指南的Multifield Search一章. 查询很少是只拥有一个match查询子句的查询.我们经常需要对一个或者多个字段使用相同或者 ...

随机推荐

  1. map和reduce 个数的设定 (Hive优化)经典

    一.    控制hive任务中的map数:  1.    通常情况下,作业会通过input的目录产生一个或者多个map任务. 主要的决定因素有: input的文件总个数,input的文件大小,集群设置 ...

  2. java JDBC与MySQL 关于日间与日期

    //MySQL Date类型 -> java.sql.Date java.sql.Date d = new java.sql.Date(Calendar.getInstance().getTim ...

  3. mac下编译安装grafana 4.2.0

    go语言在开发效率和运行效率中的优势让很多人青睐,所以有倾向打算转向go语言的开发. 下面介绍在Mac OS X中golang的开发环境配置. 1.安装brew brew是一个mac下的由ruby开发 ...

  4. SDK中常用的工具

    Android SDK包含了各种各样的定制工具,简介如下: 一.Android模拟器(Android Emulator )它是在你的计算机上运行的一个虚拟移动设备.你可以使用模拟器来在一个实际的And ...

  5. ps6-图层基础与操作技巧

    1.图层的新建.复制与删除 ctrl+j:复制图层,可以用复制选区作为新图层 Shift+Ctrl+Alt+e:在新的空白图层将下面所有的图层合并为一个图层. 2.选择复制与链接图层 在移动图层时,按 ...

  6. 魔法效果——dijkstra+堆(邻接表存储)

    dijkstra本身每次要for一遍,才能找出最小的节点,但用了堆之后,直接取出堆首就可以了. 但要注意的一点是,c++自带的stl里的priority_queue本身是先入大出的,而我们要求的是最小 ...

  7. nyoj-155-求高精度幂(java大数)

    题目链接 import java.util.*; import java.math.*; public class Main{ public static void main(String[] arg ...

  8. 真机环境spotlight光源丢失

    maya做好的模型生成的fbx,导入到unity之后,pc运行正常,到了ios真机上发现光线丢失,场景内物体都是暗暗的,查出来原因是spot光源丢失了,选中spot光源,在其Render Mode里, ...

  9. mybatis与oracle使用总结

    Oracle使用总结 1.新建表删除表 新建表语句: CREATE TABLE +表名{ } create table AFA_USER ( USER_ID VARCHAR2() not null, ...

  10. python面向对象-我的理解

    参考:博客 Vamei .廖雪峰 面向对象概念 面向对象完全可以按照自然界生物分类法来理解. 当然,它不会有自然界那么复杂. 因为我专业的关系,因此个人觉得微生物来举例很容易理解. 所有的微生物都具有 ...