Skip to main content

多字段匹配 multi_match

MultiMatchQuery 是建立在 MatchQuery 之上以允许多字段查询:

GET /_search
{
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message", "*_name" ]
}
}
}

*_name 为前缀匹配的字段

提升字段权重

可以使用特殊字符 (^) 表示法提升字段权重:

GET /_search
{
"query": {
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ]
}
}
}

subject字段的重要性是message字段的三倍。

算分类型

multi_match查询内部执行的方式取决于type参数,可以设置为

  • best_fields 查找与任何字段匹配的文档,算分来自最佳字段的分数。 默认
  • most_fields 查找与任何字段匹配的文档,算分来自每个字段的分数总和。
  • cross_fields 使用相同的分析器处理字段,就好像它们是一个大字段一样。查找任何字段中的每个单词。
  • phrase 对每个字段运行 match_phrase 查询并使用最佳字段的分数。
  • phrase_prefix 在每个字段上运行 match_phrase_prefix 查询并合并每个字段的分数。

1. best_fields

当您搜索在 同一字段 中最好找到多个词时,使用best_fields。例如,单个字段中的“brown fox”比一个字段中的“brown”和另一个字段中的“fox”更有意义。

best_fields 为每个字段生成匹配查询并将它们包装在 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
}
}
}

tie_breaker 这个参数将其他匹配语句的评分也考虑其中:

总分 =(best_fields _score) + (tie_breaker * 其他字段 _score)

2. most_fields

most_fields 匹配多个字段返回的综合评分,和best_fields的区别是总分不再是最佳字段的匹配分,而是所有字段匹配分的总和。

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" }}
]
}
}
}

每个匹配子句的分数相加,然后除以匹配子句的数量。

3. cross_fields

跨字段匹配,与 best_fields 和 most_fields 使用面向字段的算分方式不同,cross_fields 是以面向词为主体,将所有字段当成一个大字段进行关键词的匹配度算分。

例如我们期望查找 first_name:Will 以及 last_name: Smith 匹配度最高的文档。

PUT person
{
"mappings" : {
"_doc" : {
"properties" : {
"first_name" : { "type" : "text" },
"last_name" : { "type" : "text" }
}
}
}
}


POST person/_bulk
{ "index" : { "_type" : "_doc"} }
{ "first_name" : "Will","last_name":"Smith" }
{ "index" : { "_type" : "_doc"} }
{ "first_name" : "tony","last_name":"Will Minth" }
{ "index" : { "_type" : "_doc"} }
{ "first_name" : "Will","last_name":"Smith world" }
{ "index" : { "_type" : "_doc"} }
{ "first_name" : "Will Minth","last_name":"tony" }

GET person/_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "most_fields",
"fields": [ "first_name", "last_name" ]
}
}
}

# "Will Smith world" 相比 "tony Will Minth" 具备更高的评分
GET person/_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first_name", "last_name" ]
}
}
}

4. phrase 和 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" }}
]
}
}
}
tip
  • 此外,接受匹配查询中的analyze、boost、lenient、zero_terms_query,以及匹配短语查询中解释的 slop。类型 phrase_prefix 还可接受 max_expansions。
  • fuzziness 参数不能与 phrase 或 phrase_prefix 类型一起使用