标签:索引 his 文档 方案 ini 同方 active class 有助于
multi_match查询建议在match query之上,并允许多字段查询:
GET /_search { "query": { "multi_match" : { "query": "this is a test", 【1】 "fields": [ "subject", "message" ] 【2】 } } }
【1】 查询字符串
【2】被查询的字段
fields
and per-field boosting字段可以通过通配符指定,例如:
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "fields": [ "title", "*_name" ] 【1】 } } }
【1】查询title,first_name和last_name字段。
个别字段可以通过插入符号(^)来提升:
GET /_search { "query": { "multi_match" : { "query" : "this is a test", "fields" : [ "subject^3", "message" ] 【1】 } } }
【1】subject字段是message字段的3倍。
multi_match
query:内部执行multi_match查询的方式依赖于type参数,它可以被设置成:
best_fields (默认)查找与任何字段匹配的文档,但使用最佳字段中的_score。看best_fields.
most_fields 查找与任何字段匹配的文档,并联合每个字段的_score.
cross_fields 采用相同分析器处理字段,就好像他们是一个大的字段。在每个字段中查找每个单词。看cross_fields。
phrase 在每个字段上运行match_phrase查询并和每个字段的_score组合。看phrase and phrase_prefix。
phrase_prefix 在每个字段上运行match_phrase_prefix查询并和每个字段的_score组合。看phrase and phrase_prefix。
best_fields
当你在同一个字段中搜索最佳查找的多个单词时,bese_fields类型是最有效的。例如,"brown fox"单独在一个字段中比"brown"在一个字段中和"for"在另外一个字段中更有意义。
best_fields为每一个字段生成match query并在dis_max查询中包含他们,以发现单个最匹配的字段。例如这个查询:
GET /_search { "query": { "multi_match" : { "query": "brown fox", "type": "best_fields", "fields": [ "subject", "message" ], "tie_breaker": 0.3 } } }
也可以这样执行:
GET /_search { "query": { "dis_max": { "queries": [ { "match": { "subject": "brown fox" }}, { "match": { "message": "brown fox" }} ], "tie_breaker": 0.3 } } }
通常best_fields类型使用单个最佳匹配字段的score,但是假如tie_breaker被指定,则它通过以下计算score:
同时也接受analyzer
, boost
, operator
, minimum_should_match
, fuzziness
, lenient
, prefix_length
, max_expansions
, rewrite
, zero_terms_query和cutoff_frequency作为匹配查询的解释。
重要:operator
和 minimum_should_match
best_fields和most_fields类型是field-centric( 他们为每一个字段生成匹配查询)。这意味着为每一个字段单独提供operator和
minimum_should_match参数,这可能不是你想要的。
以此查询为例:
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" 【1】 } } }
【1】所有的项必须存在
该查询也可以这样执行:
(+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
换句话说,所有项必须在单个字段中存在,以匹配文档。查看cross_fields以寻找更好的解决方案。
most_fields
当查询使用不同方式包含相同文本分析的多个字段时,most_fields类型是非常有用的。例如,main字段可能包含synonyms,stemming 和没有变音符的项,second字段可能包含original项和third字段包含shingles。通过组合来自三个字段的score,我们能尽可能多的通过main字段匹配文档,但是使用second和third字段将最相似的结果推送到列表的顶部。
该查询:
GET /_search { "query": { "multi_match" : { "query": "quick brown fox", "type": "most_fields", "fields": [ "title", "title.original", "title.shingles" ] } } }
可能执行如下:
GET /_search { "query": { "bool": { "should": [ { "match": { "title": "quick brown fox" }}, { "match": { "title.original": "quick brown fox" }}, { "match": { "title.shingles": "quick brown fox" }} ] } } }
每一个match子句的score将被加在一起,然后通过match子句的数量来分割。
也接受analyzer
, boost
, operator
, minimum_should_match
, fuzziness
, lenient
, prefix_length
, max_expansions
, rewrite
, zero_terms_query和cutoff_frequency,作为match query中的解释,但请看operator and minimum_should_match。
phrase
and phrase_prefix
phrase和phrase_prefix类型行为就像best_fields,但他们使用
match_phrase或者
match_phrase_prefix查询代替match查询。
该查询:
GET /_search { "query": { "multi_match" : { "query": "quick brown f", "type": "phrase_prefix", "fields": [ "subject", "message" ] } } }
可能执行如下:
GET /_search { "query": { "dis_max": { "queries": [ { "match_phrase_prefix": { "subject": "quick brown f" }}, { "match_phrase_prefix": { "message": "quick brown f" }} ] } } }
也接受analyzer
, boost
, lenient
, slop
和zero_terms_query作为在match query中的解释。
phrase_prefix类型此外接受max_expansions。
重要:phrase,phrase_prefix和fuzziness:fuzziness参数不能被phrase和phrase_prefix类型使用
cross_fields
cross_fields类型对于多个字段应该匹配的结构文档特别有用。例如,当为“Will Smith”查询first_name和
last_name字段时,最佳匹配应该是"Will"在一个字段中并且"Smith"在另外一个字段中。
这听起来像most_fields的工作,但这种方法有两个问题。第一个问题是operator和minimum_should_match在每个前缀字段中作用,以代替前缀项(请参考explanation above)。 第二个问题是与关联性有关:在first_name和last_name字段中不同的项频率可能导致不可预期的结果。 例如,想像我们有两个人,“Will Smith”和"Smith Jones"。“Smith”作为姓是非常常见的(所以重要性很低),但是“Smith”作为名字是非常不常见的(所以重要性很高)。 假如我们搜索“Will Smith”,则“Smith Jones”文档可能显示在更加匹配的"Will Smith"上,因为first_name:smith的得分已经胜过first_name:will加last_name:smith的总分。
处理该种类型查询的一种方式是简单的将first_name和last_name索引字段放入单个full_name字段中。当然,这只能在索引时间完成。
cross_field类型尝试通过采用term-centric方法在查询时解决这些问题。首先把查询字符串分解成当个项,然后在任何字段中查询每个项,就好像它们是一个大的字段。
查询就像这样:
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }
被执行为:
+(first_name:will last_name:will) +(first_name:smith last_name:smith)
换一种说法,所有的项必须至少在匹配文档中一个字段中出现(比较the logic used for best_fields and most_fields)。
解决了两个问题中的一个。通过混合所有字段项的频率解决不同项匹配的问题,以便平衡差异。
在实践中,first_name:smith将被视为和last_name:smith具有相同的频率,加1。这将使得在first_name和last_name上的匹配具有可比较的分数,对于last_name具有微小的优势,因为它是最有可能包含simth的字段。
注意,cross_fields通常仅作用与得到1提升的短字符串字段。 否则增加,项频率和长度正常化有助于得分, 使得项统计的混合不再有任何意义。
假如你通过Validata API运行上面的查询,将返回这样的解释:
+blended("will", fields: [first_name, last_name]) +blended("smith", fields: [first_name, last_name])
也接受analyzer
, boost
, operator
, minimum_should_match
, lenient
, zero_terms_query
和cutoff_frequency
,作为match query的解释。
cross_field
and analysiscross_field类型只能在具有相同分析器的字段上以term-centric模式工作。具有相同分析器的字段如上述实例组合在一起。假如有多个组,则他们使用bool查询相结合。
例如,假如我们有相同分析器的first和last字段,增加一个同时使用edge_ngram分析器的first.edge和last.edge,该查询:
GET /_search { "query": { "multi_match" : { "query": "Jon", "type": "cross_fields", "fields": [ "first", "first.edge", "last", "last.edge" ] } } }
可能被执行为:
blended("jon", fields: [first, last]) | ( blended("j", fields: [first.edge, last.edge]) blended("jo", fields: [first.edge, last.edge]) blended("jon", fields: [first.edge, last.edge]) )
换句话说,first和last可能被组合在一起并被当做一个字段来对待,同时first.edge和last.edge可能被组合在一起并当做一个字段来对待。
具有多个组是好的,当使用operator或者minimum_should_match关联的时候,它可能遭受和most_fields和best_fields相同的问题。
你可以容易的将该查询重写为两个独立的cross_fields查询与bool查询相结合,并将minimum_should_match参数应用于其中一个:
GET /_search { "query": { "bool": { "should": [ { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "first", "last" ], "minimum_should_match": "50%" 【1】 } }, { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "*.edge" ] } } ] } } }
【1】will或smith必须存在于first或last字段。
你可以通过在查询中指定analyzer参数强制把所有字段放入相同组中。
GET /_search { "query": { "multi_match" : { "query": "Jon", "type": "cross_fields", "analyzer": "standard", 【1】 "fields": [ "first", "last", "*.edge" ] } } }
【1】对所有字段使用standard分析器
将执行如下:
blended("will", fields: [first, first.edge, last.edge, last]) blended("smith", fields: [first, first.edge, last.edge, last])
tie_breaker
默认情况,每一个per-term混合查询将使用组中任何字段的最佳分数,然后将这些分数相加,以得出最终分数。tie_breaker参数可以改变per-term混合查询的默认行为,它接受:
0.0 获取最好的分数(举例)first_name:will和last_name:will(default)
1.0 所有分数相加(举例)first_name:will和last_name:will
0.0 < n < 1.0 将单个最佳分数加上tie_breaker乘以其它每个匹配字段的分数。
重要:cross_fields
and fuzziness
fuzziness参数不能被cross_fields类型使用。
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.0/query-dsl-multi-match-query.html
标签:索引 his 文档 方案 ini 同方 active class 有助于
原文地址:http://www.cnblogs.com/benjiming/p/7096258.html