ElasticSearch DSL之Match(二)

关于match我们已经知道了ES一共提供了8种DSL语法,上篇花了大篇幅的文字介绍了match,这篇将剩余的语法继续讲解下。

match_phrase

match_phrase查询分析文本,并从分析的文本中创建一个短语查询。短语查询按照任何顺序将术语匹配到可配置的slop。
可以设置analyzer来选择使用哪个analyzer将对文本执行分析过程。它默认为字段显式映射定义,或者默认搜索分析器,例如:

{
    "query": {
        "match_phrase" : {
            "message" : {
                "query" : "a good phone",
                "analyzer" : "what_analyzer"
            }
        }
    }
}

match_phrase_prefix

match_phrase_prefix与match_phrase相同,只是它允许对文本中的最后一个术语进行前缀匹配。它接受与短语类型相同的参数。此外,它还接受max_expansions参数,可以控制最后一项将扩展多少后缀:

{
    "query": {
        "match_phrase_prefix" : {
            "message" : {
                "query" : "quick brown f",
                "max_expansions" : 10
            }
        }
    }
}

multi_match query

从名字我们就能看出来这是对多个文本进行匹配检索的语法,匹配的字段通过fields传入:

{
  "query": {
    "multi_match" : {
      "query":    "a good phone", 
      "fields": [ "name", "description" ] 
    }
  }
}

也可以使用通配符:

{
  "query": {
    "multi_match" : {
      "query":    "a good phone", 
      "fields": [ "name", "*_type" ] 
    }
  }
}

如果没有提供fields,multi_match查询默认为index.query.default_field的索引设置,默认为*.*提取映射中符合术语查询条件的所有字段,然后组合所有提取的字段来构建查询。

multi_match查询还可以通过类型参数使用不通的执行方式,有下面这几种:
1.best_fields:查找匹配任何字段的文档,但是使用最佳字段的_score。
2.most_fields:查找匹配任何字段并结合每个字段的_score的文档。
3.cross_fields:用相同的分析器处理字段,就好像它们是一个大字段一样,可以在任何字段中查找每个单词。
4.phrase:在每个字段上运行match_phrase查询,并合并每个字段的_score。
5.phrase_prefix:在每个字段上运行match_phrase_prefix查询,并组合来自每个字段的_score。

1.best_fields

搜索在同一字段中最容易找到的多个单词时,best_fields类型是最有用的。例如,“好看的手机”比一个单独的“好看的”和另一个单独的“手机”能更有效的查出目标。
best_fields类型为每个字段生成匹配查询,并将它们包装在dis_max查询中,以找到单个最佳匹配字段。例如:

{
  "query": {
    "multi_match" : {
      "query":      "good phone",
      "type":       "best_fields",
      "fields":     [ "name", "description" ],
      "tie_breaker": 0.3
    }
  }
}

上述查询会被拆解成下面的查询来执行:

{
  "query": {
    "dis_max": {
      "queries": [
        { "match": { "name": "good phone" }},
        { "match": { "description": "good phone" }}
      ],
      "tie_breaker": 0.3
    }
  }
}

通常best_fields类型使用单个最佳匹配字段的score,但如果指定了tie_breaker的值,则按照如下方式执行:
1.最佳匹配字段的得分
2.加上tie_breaker * _score用于所有其他匹配字段

2.most_fields

most_fields在查询包含相同文本的多个字段时最有用。例如,主字段可能包含同义词、词干和没有变音符号的术语。第二个字段可能包含原始术语。通过合并这三个字段的得分,我们可以将尽可能多的文档与主字段匹配。

{
  "query": {
    "multi_match" : {
      "query":      "cheap good phone",
      "type":       "most_fields",
      "fields":     [ "name", "name.ori"]
    }
  }
}

phrase和phrase_prefix

phrase和phrase_prefix的执行方式类似于best_fields,但是它们使用match_phrase或match_phrase_prefix查询而不是匹配查询。

{
  "query": {
    "multi_match" : {
      "query":      "cheap good phone",
      "type":       "phrase_prefix",
      "fields":     [ "name", "description" ]
    }
  }
}

会被翻译成成:

{
  "query": {
    "dis_max": {
      "queries": [
        { "match_phrase_prefix": { "name": "cheap good phone" }},
        { "match_phrase_prefix": { "description": "cheap good phone" }}
      ]
    }
  }
}

cross_fields

cross_fields对于需要匹配多个字段的结构化文档特别有用。例如,在查询人名“Jim Green”的姓和名字段时,在一个字段中可能会有“Jim”,而在另一个字段中可能会有“Green”。
处理这些查询的一种方法是将姓和名字段索引为一个全名字段。当然,这只能在索引时完成。cross_field就是为了解决这样的问题而被创造出来的。它首先将查询字符串分析为单个术语,然后在任何字段中查找每个术语,就好像它们是一个大字段一样。

{
  "query": {
    "multi_match" : {
      "query":      "Jim Green",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and"
    }
  }
}

这次的重心放在了multi match上,毕竟这也是除了match外另一个最常用的语法。ES提供的方法是很多的,具体用到哪些怎么用还是得看在什么场景下使用!
 

版权所属,如需转载,请注明出处:搜闲鱼

667 次浏览

发表评论

电子邮件地址不会被公开。 必填项已用*标注