查询字符串查询

编辑

本页包含关于 query_string 查询类型的信息。有关在 Elasticsearch 中运行搜索查询的信息,请参阅 搜索 API

根据提供的查询字符串,使用具有严格语法的解析器返回文档。

此查询使用 语法,根据诸如 ANDNOT 之类的运算符解析和拆分提供的查询字符串。然后,查询在返回匹配的文档之前,会独立地 分析 每个拆分后的文本。

您可以使用 query_string 查询来创建复杂的搜索,包括通配符、跨多个字段搜索等等。虽然功能多样,但查询非常严格,如果查询字符串包含任何无效语法,则会返回错误。

由于对于任何无效语法都会返回错误,因此我们不建议将 query_string 查询用于搜索框。

如果您不需要支持查询语法,请考虑使用 match 查询。如果您需要查询语法的功能,请使用 simple_query_string 查询,它不那么严格。

请求示例

编辑

在运行以下搜索时,query_string 查询会将 (new york city) OR (big apple) 拆分为两部分:new york citybig applecontent 字段的分析器然后独立地将每个部分转换为标记,然后再返回匹配的文档。因为查询语法不使用空格作为运算符,所以 new york city 会按原样传递给分析器。

resp = client.search(
    query={
        "query_string": {
            "query": "(new york city) OR (big apple)",
            "default_field": "content"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        query: '(new york city) OR (big apple)',
        default_field: 'content'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "query": "(new york city) OR (big apple)",
	      "default_field": "content"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      query: "(new york city) OR (big apple)",
      default_field: "content",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "query": "(new york city) OR (big apple)",
      "default_field": "content"
    }
  }
}

query_string 的顶层参数

编辑
query
(必需,字符串)您希望解析并用于搜索的查询字符串。请参阅 查询字符串语法
default_field

(可选,字符串)如果查询字符串中未提供字段,则要搜索的默认字段。支持通配符 (*)。

默认为 index.query.default_field 索引设置,其默认值为 ** 值提取所有符合术语查询条件的字段,并筛选元数据字段。如果未指定 prefix,则会将所有提取的字段组合起来以构建查询。

跨所有符合条件的字段进行搜索不包括 嵌套文档。使用 nested 查询 来搜索这些文档。

对于具有大量字段的映射,跨所有符合条件的字段进行搜索可能会很昂贵。

可以一次查询的字段乘以术语的数量有限制。它由 indices.query.bool.max_clause_count 搜索设置 定义。

allow_leading_wildcard
(可选,布尔值)如果为 true,则允许通配符 *? 作为查询字符串的第一个字符。默认为 true
analyze_wildcard
(可选,布尔值)如果为 true,则查询会尝试分析查询字符串中的通配符术语。默认为 false
analyzer
(可选,字符串)分析器,用于将查询字符串中的文本转换为标记。默认为为 default_field 映射的 索引时分析器。如果未映射任何分析器,则使用索引的默认分析器。
auto_generate_synonyms_phrase_query
(可选,布尔值)如果为 true,则会自动为多术语同义词创建 匹配短语 查询。默认为 true。有关示例,请参阅 同义词和 query_string 查询
boost

(可选,浮点数)用于降低或提高查询的 相关性分数 的浮点数。默认为 1.0

Boost 值相对于默认值 1.0。介于 01.0 之间的 boost 值会降低相关性分数。大于 1.0 的值会增加相关性分数。

default_operator

(可选,字符串)如果未指定运算符,则用于解释查询字符串中文本的默认布尔逻辑。有效值为

OR(默认)
例如,capital of Hungary 的查询字符串被解释为 capital OR of OR Hungary
AND
例如,capital of Hungary 的查询字符串被解释为 capital AND of AND Hungary
enable_position_increments
(可选,布尔值)如果为 true,则在从 query_string 搜索构造的查询中启用位置增量。默认为 true
fields

(可选,字符串数组)要搜索的字段数组。支持通配符 (*)。

您可以使用此参数查询来跨多个字段进行搜索。请参阅 搜索多个字段

fuzziness
(可选,字符串)允许模糊匹配的最大编辑距离。有关模糊语法,请参阅 模糊性
fuzzy_max_expansions
(可选,整数)查询扩展用于模糊匹配的最大术语数。默认为 50
fuzzy_prefix_length
(可选,整数)模糊匹配中保持不变的起始字符数。默认为 0
fuzzy_transpositions
(可选,布尔值)如果为 true,则用于模糊匹配的编辑包括两个相邻字符的换位 (ab → ba)。默认为 true
lenient
(可选,布尔值)如果为 true,则会忽略基于格式的错误,例如为 数字 字段提供文本值。默认为 false
max_determinized_states

(可选,整数)查询所需的 自动机状态 的最大数量。默认值为 10000

Elasticsearch 在内部使用 Apache Lucene 来解析正则表达式。Lucene 将每个正则表达式转换为包含若干确定性状态的有限自动机。

您可以使用此参数来防止该转换意外地消耗过多资源。您可能需要增加此限制才能运行复杂的正则表达式。

minimum_should_match
(可选,字符串)必须匹配才能返回文档的最小子句数。有关有效值和更多信息,请参阅 minimum_should_match 参数。有关示例,请参阅 minimum_should_match 的工作原理
quote_analyzer

(可选,字符串)分析器,用于将查询字符串中带引号的文本转换为标记。默认为为 default_field 映射的 search_quote_analyzer

对于带引号的文本,此参数会覆盖 analyzer 参数中指定的分析器。

phrase_slop
(可选,整数)短语的匹配标记之间允许的最大位置数。默认为 0。如果为 0,则需要完全匹配的短语。转置的术语的 slop 为 2
quote_field_suffix

(可选,字符串)追加到查询字符串中带引号的文本的后缀。

您可以使用此后缀为精确匹配使用不同的分析方法。请参阅 将精确搜索与词干提取混合

rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅 rewrite 参数
time_zone

(可选,字符串)用于将查询字符串中的 date 值转换为 UTC 的 协调世界时 (UTC) 偏移量IANA 时区

有效值是 ISO 8601 UTC 偏移量,例如 +01:00 或 -08:00,以及 IANA 时区 ID,例如 America/Los_Angeles

time_zone 参数 影响 now日期数学 值。now 始终是 UTC 的当前系统时间。但是,time_zone 参数确实会转换使用 now日期数学舍入 计算的日期。例如,time_zone 参数将转换 now/d 的值。

说明

编辑

查询字符串语法

编辑

查询字符串“微型语言”由 查询字符串search API 中的 q 查询字符串参数使用。

查询字符串被解析为一系列术语运算符。术语可以是单个词 — quickbrown — 或由双引号括起来的短语 — "quick brown" — 它搜索短语中的所有单词,并按相同的顺序搜索。

运算符允许您自定义搜索 — 下面解释了可用的选项。

字段名称
编辑

您可以在查询语法中指定要搜索的字段

  • 其中 status 字段包含 active

    status:active
  • 其中 title 字段包含 quickbrown

    title:(quick OR brown)
  • 其中 author 字段包含确切的短语 "john smith"

    author:"John Smith"
  • 其中 first name 字段包含 Alice(请注意我们如何使用反斜杠转义空格)

    first\ name:Alice
  • 其中任何字段 book.titlebook.contentbook.date 包含 quickbrown(请注意我们如何使用反斜杠转义 *

    book.\*:(quick OR brown)
  • 其中字段 title 具有任何非空值

    _exists_:title
通配符
编辑

可以使用通配符对单个词条进行搜索,使用 ? 替换单个字符,使用 * 替换零个或多个字符。

qu?ck bro*

请注意,通配符查询可能会占用大量内存并且性能非常差——试想一下,要匹配查询字符串 "a* b* c*" 需要查询多少个词条。

纯通配符 \* 为了提高效率会被重写为 exists 查询。因此,通配符 "field:*" 将匹配具有空值的文档,如下所示:

{
  "field": ""
}

...如果字段缺失或设置为显式空值,则不会匹配,如下所示:

{
  "field": null
}

允许在单词开头使用通配符(例如 "*ing")的开销特别大,因为需要检查索引中的所有词条,以防它们匹配。可以通过将 allow_leading_wildcard 设置为 false 来禁用前导通配符。

只会应用在字符级别操作的分析链部分。因此,例如,如果分析器同时执行小写转换和词干提取,则只会应用小写转换:对缺少某些字母的单词执行词干提取是错误的。

通过将 analyze_wildcard 设置为 true,以 * 结尾的查询将被分析,并且将基于不同的词条构建一个布尔查询,以确保前 N-1 个词条的精确匹配,以及最后一个词条的前缀匹配。

正则表达式
编辑

可以通过将正则表达式模式包裹在正斜杠("/")中,将其嵌入到查询字符串中。

name:/joh?n(ath[oa]n)/

支持的正则表达式语法在 正则表达式语法 中解释。

allow_leading_wildcard 参数对正则表达式没有任何控制作用。诸如以下查询字符串将强制 Elasticsearch 访问索引中的每个词条:

/.*n/

请谨慎使用!

模糊度
编辑

您可以使用 ~ 运算符运行 模糊查询

quikc~ brwn~ foks~

对于这些查询,查询字符串会被规范化。如果存在,则仅应用分析器中的某些过滤器。有关适用过滤器的列表,请参阅规范器

该查询使用 Damerau-Levenshtein 距离来查找最大变更次数为两次的所有词条,其中变更指的是单个字符的插入、删除或替换,或者两个相邻字符的换位。

默认的编辑距离2,但是编辑距离为 1 应该足以捕获 80% 的人为拼写错误。它可以指定为:

quikc~1

避免将模糊度与通配符混用

支持混合使用 模糊通配符 运算符。当混合使用时,其中一个运算符将不会被应用。例如,您可以搜索 app~1(模糊)或 app*(通配符),但搜索 app*~1 不会应用模糊运算符(~1)。

邻近搜索
编辑

短语查询(例如 "john smith")期望所有词条都按照完全相同的顺序排列,而邻近查询则允许指定的单词相隔较远或顺序不同。与模糊查询可以为单词中的字符指定最大编辑距离的方式相同,邻近搜索允许我们指定短语中单词的最大编辑距离。

"fox quick"~5

字段中的文本越接近查询字符串中指定的原始顺序,该文档就被认为与该查询的相关性越高。与上面的示例查询相比,短语 "quick fox" 被认为比 "quick brown fox" 更相关。

范围
编辑

可以为日期、数字或字符串字段指定范围。包含范围用方括号 [min TO max] 指定,不包含范围用花括号 {min TO max} 指定。

  • 2012 年的所有日期

    date:[2012-01-01 TO 2012-12-31]
  • 数字 1..5

    count:[1 TO 5]
  • 介于 alphaomega 之间的标签,不包括 alphaomega

    tag:{alpha TO omega}
  • 从 10 开始的数字

    count:[10 TO *]
  • 2012 年之前的日期

    date:{* TO 2012-01-01}

花括号和方括号可以组合使用

  • 从 1 到 5 但不包括 5 的数字

    count:[1 TO 5}

一侧无界的范围可以使用以下语法

age:>10
age:>=10
age:<10
age:<=10

要将上限和下限与简化语法组合,您需要使用 AND 运算符连接两个子句

age:(>=10 AND <20)
age:(+>=10 +<20)

在查询字符串中解析范围可能很复杂且容易出错。使用显式 范围查询 更可靠。

加权
编辑

使用加权运算符 ^ 使一个词条比另一个词条更相关。例如,如果我们想找到所有关于狐狸的文档,但我们对快速的狐狸特别感兴趣:

quick^2 fox

默认的 boost 值为 1,但可以是任何正浮点数。介于 0 和 1 之间的加权值会降低相关性。

加权也可以应用于短语或组:

"john smith"^2   (foo bar)^4
布尔运算符
编辑

默认情况下,所有词条都是可选的,只要有一个词条匹配即可。搜索 foo bar baz 将找到任何包含 foobarbaz 中的一个或多个的文档。我们已经在上面讨论了 default_operator,它允许您强制要求所有词条,但是查询字符串本身也可以使用布尔运算符以提供更多控制。

首选运算符是 +(此词条必须存在)和 -(此词条不得存在)。所有其他词条都是可选的。例如,此查询:

quick brown +fox -news

表示:

  • fox 必须存在
  • news 必须不存在
  • quickbrown 是可选的——它们的存在会增加相关性

还支持熟悉的布尔运算符 ANDORNOT(也写作 &&||!),但请注意,它们不遵循通常的优先级规则,因此,当多个运算符一起使用时,应使用括号。例如,之前的查询可以重写为:

((quick AND fox) OR (brown AND fox) OR fox) AND NOT news
这种形式现在正确地复制了原始查询中的逻辑,但是相关性评分与原始评分几乎没有相似之处。

相反,使用 match 查询 重写的相同查询将如下所示:

{
    "bool": {
        "must":     { "match": "fox"         },
        "should":   { "match": "quick brown" },
        "must_not": { "match": "news"        }
    }
}
分组
编辑

可以使用括号将多个词条或子句分组在一起,以形成子查询

(quick OR brown) AND fox

可以使用组来定位特定字段,或提升子查询的结果

status:(active OR pending) title:(full text search)^2
保留字符
编辑

如果您需要在查询本身中使用任何作为运算符的字符(而不是作为运算符),则应使用前导反斜杠对其进行转义。例如,要搜索 (1+1)=2,您需要将查询写为 \(1\+1\)\=2。当使用 JSON 作为请求正文时,需要两个前导反斜杠(\\);反斜杠是 JSON 字符串中保留的转义字符。

resp = client.search(
    index="my-index-000001",
    query={
        "query_string": {
            "query": "kimchy\\!",
            "fields": [
                "user.id"
            ]
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      query_string: {
        query: 'kimchy\\!',
        fields: [
          'user.id'
        ]
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  query: {
    query_string: {
      query: "kimchy\\!",
      fields: ["user.id"],
    },
  },
});
console.log(response);
GET /my-index-000001/_search
{
  "query" : {
    "query_string" : {
      "query" : "kimchy\\!",
      "fields"  : ["user.id"]
    }
  }
}

保留字符包括:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

未能正确转义这些特殊字符可能会导致语法错误,从而阻止您的查询运行。

<> 根本无法转义。防止它们尝试创建范围查询的唯一方法是从查询字符串中完全删除它们。

空格和空查询
编辑

空格不被视为运算符。

如果查询字符串为空或仅包含空格,则查询将产生空结果集。

避免对嵌套文档使用 query_string 查询
编辑

query_string 搜索不会返回 嵌套文档。要搜索嵌套文档,请使用 嵌套查询

搜索多个字段
编辑

您可以使用 fields 参数在多个字段上执行 query_string 搜索。

对多个字段运行 query_string 查询的想法是将每个查询词条扩展为如下所示的 OR 子句:

field1:query_term OR field2:query_term | ...

例如,以下查询

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "content",
                "name"
            ],
            "query": "this AND that"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'content',
          'name'
        ],
        query: 'this AND that'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "content",
	        "name"
	      ],
	      "query": "this AND that"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["content", "name"],
      query: "this AND that",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "fields": [ "content", "name" ],
      "query": "this AND that"
    }
  }
}

匹配与以下相同的单词:

resp = client.search(
    query={
        "query_string": {
            "query": "(content:this OR name:this) AND (content:that OR name:that)"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        query: '(content:this OR name:this) AND (content:that OR name:that)'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "query": "(content:this OR name:this) AND (content:that OR name:that)"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      query: "(content:this OR name:this) AND (content:that OR name:that)",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "query": "(content:this OR name:this) AND (content:that OR name:that)"
    }
  }
}

由于从单个搜索词条生成了多个查询,因此使用带有 tie_breakerdis_max 查询自动完成它们的组合。例如(使用 ^5 表示法将 name 加权 5):

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "content",
                "name^5"
            ],
            "query": "this AND that OR thus",
            "tie_breaker": 0
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'content',
          'name^5'
        ],
        query: 'this AND that OR thus',
        tie_breaker: 0
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "content",
	        "name^5"
	      ],
	      "query": "this AND that OR thus",
	      "tie_breaker": 0
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["content", "name^5"],
      query: "this AND that OR thus",
      tie_breaker: 0,
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string" : {
      "fields" : ["content", "name^5"],
      "query" : "this AND that OR thus",
      "tie_breaker" : 0
    }
  }
}

简单的通配符也可以用于在文档的特定内部元素中搜索。例如,如果有一个包含多个字段(或包含字段的内部对象)的 city 对象,则可以自动搜索所有“city”字段。

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "city.*"
            ],
            "query": "this AND that OR thus"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'city.*'
        ],
        query: 'this AND that OR thus'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "city.*"
	      ],
	      "query": "this AND that OR thus"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["city.*"],
      query: "this AND that OR thus",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string" : {
      "fields" : ["city.*"],
      "query" : "this AND that OR thus"
    }
  }
}

另一种方法是在查询字符串本身中提供通配符字段搜索(正确转义 * 符号),例如:city.\*:something

resp = client.search(
    query={
        "query_string": {
            "query": "city.\\*:(this AND that OR thus)"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        query: 'city.\\*:(this AND that OR thus)'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "query": "city.\\*:(this AND that OR thus)"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      query: "city.\\*:(this AND that OR thus)",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string" : {
      "query" : "city.\\*:(this AND that OR thus)"
    }
  }
}

由于 \(反斜杠)是 json 字符串中的特殊字符,因此需要对其进行转义,因此以上 query_string 中有两个反斜杠。

fields 参数还可以包含基于模式的字段名称,从而可以自动扩展到相关字段(包括动态引入的字段)。例如:

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "content",
                "name.*^5"
            ],
            "query": "this AND that OR thus"
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'content',
          'name.*^5'
        ],
        query: 'this AND that OR thus'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "content",
	        "name.*^5"
	      ],
	      "query": "this AND that OR thus"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["content", "name.*^5"],
      query: "this AND that OR thus",
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string" : {
      "fields" : ["content", "name.*^5"],
      "query" : "this AND that OR thus"
    }
  }
}
多字段搜索的附加参数
编辑

当针对多个字段运行 query_string 查询时,支持以下附加参数。

type

(可选,字符串)确定查询如何匹配文档并对其评分。有效值为:

best_fields(默认)
查找与任何字段匹配的文档,并使用任何匹配字段中最高的 _score。请参阅 best_fields
bool_prefix
在每个字段上创建一个 match_bool_prefix 查询,并合并每个字段的 _score。请参阅 bool_prefix
cross_fields
将具有相同 analyzer 的字段视为一个大字段。在任何字段中查找每个词。请参阅 cross_fields
most_fields
查找与任何字段匹配的文档,并合并每个字段的 _score。请参阅 most_fields
phrase
在每个字段上运行 match_phrase 查询,并使用最佳字段的 _score。请参阅 phrasephrase_prefix
phrase_prefix
在每个字段上运行 match_phrase_prefix 查询,并使用最佳字段的 _score。请参阅 phrasephrase_prefix

注意:根据 type 值,可能会提供其他顶层 multi_match 参数。

同义词和 query_string 查询

编辑

query_string 查询支持使用 synonym_graph 标记过滤器的多词同义词扩展。使用此过滤器时,解析器会为每个多词同义词创建一个短语查询。例如,以下同义词:ny, new york 将产生

(ny OR ("new york"))

也可以匹配带有连词的多词同义词

$params = [
    'body' => [
        'query' => [
            'query_string' => [
                'default_field' => 'title',
                'query' => 'ny city',
                'auto_generate_synonyms_phrase_query' => false,
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    query={
        "query_string": {
            "default_field": "title",
            "query": "ny city",
            "auto_generate_synonyms_phrase_query": False
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        default_field: 'title',
        query: 'ny city',
        auto_generate_synonyms_phrase_query: false
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "default_field": "title",
	      "query": "ny city",
	      "auto_generate_synonyms_phrase_query": false
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      default_field: "title",
      query: "ny city",
      auto_generate_synonyms_phrase_query: false,
    },
  },
});
console.log(response);
GET /_search
{
   "query": {
       "query_string" : {
           "default_field": "title",
           "query" : "ny city",
           "auto_generate_synonyms_phrase_query" : false
       }
   }
}

上面的示例创建一个布尔查询

(ny OR (new AND york)) city

该查询匹配包含术语 ny 或连词 new AND york 的文档。默认情况下,参数 auto_generate_synonyms_phrase_query 设置为 true

minimum_should_match 的工作原理

编辑

query_string 将查询围绕每个运算符拆分,为整个输入创建一个布尔查询。您可以使用 minimum_should_match 来控制结果查询中应该匹配的“should”子句的数量。

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "title"
            ],
            "query": "this that thus",
            "minimum_should_match": 2
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'title'
        ],
        query: 'this that thus',
        minimum_should_match: 2
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "title"
	      ],
	      "query": "this that thus",
	      "minimum_should_match": 2
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["title"],
      query: "this that thus",
      minimum_should_match: 2,
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title"
      ],
      "query": "this that thus",
      "minimum_should_match": 2
    }
  }
}

上面的示例创建一个布尔查询

(title:this title:that title:thus)~2

该查询匹配在单个字段 title 中至少包含 thisthatthus 中两个术语的文档。

minimum_should_match 如何用于多个字段

编辑
resp = client.search(
    query={
        "query_string": {
            "fields": [
                "title",
                "content"
            ],
            "query": "this that thus",
            "minimum_should_match": 2
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'title',
          'content'
        ],
        query: 'this that thus',
        minimum_should_match: 2
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "title",
	        "content"
	      ],
	      "query": "this that thus",
	      "minimum_should_match": 2
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["title", "content"],
      query: "this that thus",
      minimum_should_match: 2,
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this that thus",
      "minimum_should_match": 2
    }
  }
}

上面的示例创建一个布尔查询

((content:this content:that content:thus) | (title:this title:that title:thus))

该查询匹配在字段 titlecontent 上具有最大析取的文档。这里不能应用 minimum_should_match 参数。

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "title",
                "content"
            ],
            "query": "this OR that OR thus",
            "minimum_should_match": 2
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'title',
          'content'
        ],
        query: 'this OR that OR thus',
        minimum_should_match: 2
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "title",
	        "content"
	      ],
	      "query": "this OR that OR thus",
	      "minimum_should_match": 2
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["title", "content"],
      query: "this OR that OR thus",
      minimum_should_match: 2,
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this OR that OR thus",
      "minimum_should_match": 2
    }
  }
}

添加显式运算符会强制将每个术语视为单独的子句。

上面的示例创建一个布尔查询

((content:this | title:this) (content:that | title:that) (content:thus | title:thus))~2

该查询匹配至少包含三个“should”子句中的两个的文档,每个子句都由每个术语的字段上的最大析取组成。

minimum_should_match 如何用于跨字段搜索

编辑

type 字段中的 cross_fields 值表示在分析输入时,具有相同分析器的字段会分组在一起。

resp = client.search(
    query={
        "query_string": {
            "fields": [
                "title",
                "content"
            ],
            "query": "this OR that OR thus",
            "type": "cross_fields",
            "minimum_should_match": 2
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      query_string: {
        fields: [
          'title',
          'content'
        ],
        query: 'this OR that OR thus',
        type: 'cross_fields',
        minimum_should_match: 2
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "query_string": {
	      "fields": [
	        "title",
	        "content"
	      ],
	      "query": "this OR that OR thus",
	      "type": "cross_fields",
	      "minimum_should_match": 2
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    query_string: {
      fields: ["title", "content"],
      query: "this OR that OR thus",
      type: "cross_fields",
      minimum_should_match: 2,
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "query_string": {
      "fields": [
        "title",
        "content"
      ],
      "query": "this OR that OR thus",
      "type": "cross_fields",
      "minimum_should_match": 2
    }
  }
}

上面的示例创建一个布尔查询

(blended(terms:[field2:this, field1:this]) blended(terms:[field2:that, field1:that]) blended(terms:[field2:thus, field1:thus]))~2

该查询匹配至少包含三个按术语混合查询中的两个的文档。

允许高开销查询

编辑

查询字符串查询可以在内部转换为 prefix query,这意味着如果禁用前缀查询(如 此处 所述),则不会执行查询,并且会抛出异常。