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. MSDN 单机 MVC 帮助文档

    因为微软的mvc框架也是从开源框架演变而来的,所以微软没把mvc帮助文档放到单击帮助文档中.sososos下载好msdn单机帮助后,却找不到 System.Web.MVC 等命名空间的东西. 解决办法 ...

  2. Xcode 查找 TODO 清单

    在 Xcode 中按 Shift+Command+F,显示在项目中查找窗口,选择按正则表达式查找(Find > Regular Expression): TODO:  //\s*\bTODO\s ...

  3. CTR点击率简介

    点击率 简介 在搜索引擎(百度.谷歌)中输入关键词后进行搜索,然后按竞价等因素把相关的网页按顺序进行排列出来,然后用户会选择自己感兴趣的网站点击进去:把一个网站所有搜索出来的次数作为总次数,把用户点击 ...

  4. 在.Net下使用redis基于StackExchange.Redis--登录功能

    研究了下redis在.net下的使用,因为以前在java上用redis用的是jedis操作,在.net不是很熟悉,在网站上也看了一部分的.net下redis的使用,大部分都是ServiceStack. ...

  5. Leetcode 969. Pancake Sorting

    每次找到当前最大数,转两下把最大数转到最右边.重复这个操作,直到都转完. 时间复杂度O(n**2) class Solution(object): def pancakeSort(self, A): ...

  6. ecmall中的分页问题

    <ecmall>Ecmall系统自带的分页功能 在Ecmall的二次开发中,分页是必不可少的.这个系统已经自带了分页功能,下面来看看如何使用这个分页. 下面是一个自定义的类,用于查看订单的 ...

  7. [leetcode]_Flatten Binary Tree to Linked List

    题目:将一棵二叉树履平成一个类似Linked-list的东西. 思路:该过程类似于二叉树的前序遍历,但是遍历代码,我处理不来参数的变化.没AC. -------->写的很好的解题博客 参考上述博 ...

  8. 重温CLR(一)CLR基础

    如果一个C#developer,对CLR没有了解,那就只能是入门级别.未来.NET CORE是趋势,但是.NET CORE 也是基于CoreCLR的,而CLR和CoreCLR其实差别不大,从runti ...

  9. andriod&linux&c函数原型

    1.dlopen 功能:打开一个动态链接库,并返回动态链接库的句柄 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * ...

  10. UOJ #55 & 洛谷 P3920 紫荆花之恋 —— 动态点分治+替罪羊树

    题目:http://uoj.ac/problem/55 https://www.luogu.org/problemnew/show/P3920 参考博客:https://www.cnblogs.com ...