multi_match查询

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

NOTE

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

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

  1. {
  2. "dis_max": {
  3. "queries": [
  4. {
  5. "match": {
  6. "title": {
  7. "query": "Quick brown fox",
  8. "minimum_should_match": "30%"
  9. }
  10. }
  11. },
  12. {
  13. "match": {
  14. "body": {
  15. "query": "Quick brown fox",
  16. "minimum_should_match": "30%"
  17. }
  18. }
  19. },
  20. ],
  21. "tie_breaker": 0.3
  22. }
  23. }

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

  1. {
  2. "multi_match": {
  3. "query": "Quick brown fox",
  4. "type": "best_fields",
  5. "fields": [ "title", "body" ],
  6. "tie_breaker": 0.3,
  7. "minimum_should_match": "30%"
  8. }
  9. }

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

在字段名中使用通配符

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

  1. {
  2. "multi_match": {
  3. "query": "Quick brown fox",
  4. "fields": "*_title"
  5. }
  6. }

提升个别字段

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

  1. {
  2. "multi_match": {
  3. "query": "Quick brown fox",
  4. "fields": [ "*_title", "chapter_title^2" ]
  5. }
  6. }

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):

  1. DELETE /my_index
  2.  
  3. PUT /my_index
  4. {
  5. "settings": { "number_of_shards": },
  6. "mappings": {
  7. "my_type": {
  8. "properties": {
  9. "title": {
  10. "type": "string",
  11. "analyzer": "english",
  12. "fields": {
  13. "std": {
  14. "type": "string",
  15. "analyzer": "standard"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }

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

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

  1. PUT /my_index/my_type/
  2. { "title": "My rabbit jumps" }
  3.  
  4. PUT /my_index/my_type/
  5. { "title": "Jumping jack rabbits" }

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

  1. GET /my_index/_search
  2. {
  3. "query": {
  4. "match": {
  5. "title": "jumping rabbits"
  6. }
  7. }
  8. }

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

  1. {
  2. "hits": [
  3. {
  4. "_id": "",
  5. "_score": 0.42039964,
  6. "_source": {
  7. "title": "My rabbit jumps"
  8. }
  9. },
  10. {
  11. "_id": "",
  12. "_score": 0.42039964,
  13. "_source": {
  14. "title": "Jumping jack rabbits"
  15. }
  16. }
  17. ]
  18. }

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

  1. GET /my_index/_search
  2. {
  3. "query": {
  4. "multi_match": {
  5. "query": "jumping rabbits",
  6. "type": "most_fields",
  7. "fields": [ "title", "title.std" ]
  8. }
  9. }
  10. }

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

  1. {
  2. "hits": [
  3. {
  4. "_id": "",
  5. "_score": 0.8226396,
  6. "_source": {
  7. "title": "Jumping jack rabbits"
  8. }
  9. },
  10. {
  11. "_id": "",
  12. "_score": 0.10741998,
  13. "_source": {
  14. "title": "My rabbit jumps"
  15. }
  16. }
  17. ]
  18. }

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

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

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

  1. GET /my_index/_search
  2. {
  3. "query": {
  4. "multi_match": {
  5. "query": "jumping rabbits",
  6. "type": "most_fields",
  7. "fields": [ "title^10", "title.std" ]
  8. }
  9. }
  10. }

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. 防止php重复提交表单更安全的方法

    Token.php <?php /* * Created on 2013-3-25 * * To change the template for this generated file go t ...

  2. php 实现微信模拟登陆、获取用户列表及群发消息功能示例

    本文实例讲述了php实现微信模拟登陆.获取用户列表及群发消息功能.分享给大家供大家参考,具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

  3. SQL Server循环插入数据

    --循环执行插入10000条数据declare @ID intdeclare @eigyousyocode nvarchar(16)declare @datet datetimedeclare @pl ...

  4. Git_学习_07_ 推送修改到远端

    一.操作流程 多人协作时,若自己的本地代码有了修改,想提交自己的代码,就需要按照以下步骤操作: 1.确认修改正确 使用以下命令,查看有哪些是自己未提交的代码 git status 2.拉取远程最新代码 ...

  5. php程序员应该掌握的技能包

    作为一名web开发者来说,不论是php还是java web,就我目前掌握的知识来说,个人认为应该掌握以下几个方面的内容 1 基础的编程语言,这个好像是废话 2 软件设计的思想,如面向对象.mvc.各种 ...

  6. nyoj-952-最大四边形 (向量叉乘)

    题目链接 /* Name:nyoj-952-最大四边形 Copyright: Author: Date: 2018/4/27 10:46:24 Description: 枚举一条对角线,再选择一个 看 ...

  7. python 生成唯一字符串UUID与MD5

    1 Python使用UUID库生成唯一ID UUID是128位的全局唯一标识符,通常由32字节的字符串表示,保证时间和空间的唯一性 通过MAC地址.时间戳.命名空间.随机数.伪随机数来保证生成ID的唯 ...

  8. BeetleX高性能通讯开源组件

    net core高性能通讯开源组件BeetleX https://www.cnblogs.com/smark/p/9617682.html BeetleX beetleX是基于dotnet core实 ...

  9. vue-router导航守卫

    导航守卫 译者注 “导航”表示路由正在发生改变. 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航.有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件 ...

  10. swing之gridlayout

    package gui1; import java.awt.FlowLayout; import java.awt.GridLayout; import javax.swing.JButton; im ...