关于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提供的方法是很多的,具体用到哪些怎么用还是得看在什么场景下使用!
版权所属,如需转载,请注明出处:搜闲鱼