本地英文版地址: ../en/query-dsl-query-string-query.html
使用具有严格语法的解析器,根据提供的查询字符串返回文档。
该查询使用一种语法,根据运算符(如AND
或 NOT
)来解析和拆分所给的查询字符串。
在返回匹配的文档之前,查询会单独分析每个拆分出的文本。
可以使用 query_string
查询创建包含通配符的复杂搜索、跨多个字段的搜索等等。
虽然该查询是通用的,但它却很严格,如果查询字符串包含任何无效语法,就会返回错误。
因为它会因为任何无效的语法而返回错误,所以我们不建议对搜索框使用 query_string
查询。
如果不需要支持查询语法,可以考虑使用 match
查询。
如果需要查询语法的特性,请使用 simple_query_string
查询,它没有那么严格。
当执行下面的搜索时,query_string
查询将 (new york city) OR (big apple)
拆分成两个部分:new york city
和 big apple
。
然后,在返回匹配的文档之前,content
字段的分析器单独将每个部分转换成词元(token)。
因为查询语法不使用空格作为运算符,所以 new york city
按原样传递给分析器。
GET /_search { "query": { "query_string" : { "query" : "(new york city) OR (big apple)", "default_field" : "content" } } }
-
query
- (必需的, string) 希望解析并用于搜索的查询字符串。参考查询字符串语法。
-
default_field
-
(可选, string) 如果查询字符串中没有指定字段,你希望搜索的默认字段。
默认为
index.query.default_field
索引设置,其默认值为*
。*
值提取符合条件查询的所有字段,并过滤元数据字段。 如果没有指定prefix
,则将所有提取出来的字段组合起来构建一个查询。在所有符合要求的字段中搜索并不会包括 嵌套文档,请使用
nested
查询 来搜索这些文档。对于包含大量字段的映射,在所有符合条件的字段中进行搜索的成本可能会非常高。
一次可以查询的字段数量是有限制的。 它由
indices.query.bool.max_clause_count
搜索设置定义,默认为 1024。 -
allow_leading_wildcard
-
(可选, boolean) 如果为
true
,通配符*
和?
允许作为查询字符串的第一个字符。默认为true
。 -
analyze_wildcard
-
(可选, boolean) 如果为
true
,查询将尝试分析查询字符串中的通配符。默认为false
。 -
analyzer
-
(可选, string) 用于将查询字符串中的文本转换为词元(token)的分析器 。
默认为字段
default_field
所映射的 索引时使用的分析器。 如果没有映射分析器,则使用索引的默认分析器。 -
auto_generate_synonyms_phrase_query
-
(可选, boolean) 如果为
true
,将自动为多词项同义词创建 匹配短语(match phrase) 查询。 默认为true
。 有关示例请参考 同义词和query_string
查询。 -
boost
-
(可选, float) 用于降低或增加查询的相关性评分的浮点数。默认为
1.0
。boost 值是相对于默认值
1.0
的。 当它在0
和1.0
之间时会降低相关性评分,而大于1.0
时会增加相关性评分。 -
default_operator
-
(可选, string) 未指定运算符时,用于解释查询字符串中的文本的默认的布尔逻辑。有效值有:
-
OR
(默认) -
比如,查询字符串
capital of Hungary
被解释为capital OR of OR Hungary
。 -
AND
-
比如,查询字符串
capital of Hungary
被解释为capital AND of AND Hungary
。
-
-
enable_position_increments
-
(可选, boolean) 如果为
true
,则在由query_string
搜索构建的查询中启用位置增量。默认为true
。 -
fields
-
(可选, array of strings) 你想搜索的字段的数组。
可以使用此参数跨多个字段进行搜索。参考搜索多个字段。
-
fuzziness
- (可选, string) 匹配时的最大编辑距离。有效值及更多信息请参考 模糊性。
-
fuzzy_max_expansions
-
(可选, integer) 模糊匹配查询能扩展到的最大词项数。默认为
50
。 -
fuzzy_prefix_length
-
(可选, integer) 模糊匹配的起始字符保持不变的字符数量。默认为
0
。 -
fuzzy_transpositions
-
(可选, boolean) 如果为
true
,模糊匹配的编辑可以包含两个相邻字符的交换(ab → ba)。默认为true
。 -
lenient
-
(可选, boolean) 如果为
true
,则忽略基于格式的错误,例如为 numeric 字段提供 text 值。 默认为false
。 -
max_determinized_states
-
(可选, integer) 查询所需的自动机状态的最大值。默认为
10000
。Elasticsearch 内部使用Apache Lucene解析正则表达式。 Lucene 将每个正则表达式转换成一个包含许多确定状态的有限自动机。
可以使用此参数来防止该转换无意中消耗太多资源。你可能需要提高这个限制来运行复杂的正则表达式。
-
minimum_should_match
-
(可选, string) 要返回的文档必须匹配的最小子句数。
有效值及更多信息请参考
minimum_should_match
参数。 查看minimum_should_match
如何工作的示例。 -
quote_analyzer
-
(可选, string) 用于将查询字符串中的引用文本转换为词元(token)的分析器。 默认为字段
default_field
映射的search_quote_analyzer
。对于引用的文本,此参数会覆盖
analyzer
参数中指定的分析器。 -
phrase_slop
-
(可选, integer) 短语的匹配词元之间允许的最大位置数。默认为
0
。 如果为0
,则要求精确的短语匹配。 颠倒顺序的词项的 slop 的值为2
。 -
quote_field_suffix
-
(可选, string) 查询字符串中附加到引用文本的后缀。
可以使用此后缀来使用不同的分析方法进行精确匹配。参考 将精确搜索与词干混合。
-
rewrite
-
(可选, string) 用于重写查询的方法。有效值及更多信息请参考
rewrite
参数。 -
time_zone
-
(可选, string) 协调世界时(UTC)时差或 IANA时区,用于将查询字符串中的
date
值转换为 UTC。有效值包括 ISO 8601 UTC 时差,如
+01:00
或-08:00
,以及 IANA 时区识别名称,如America/Los_Angeles
。
查询字符串“迷你语言”由 search
API中的 查询字符串和 q
查询字符串参数使用。
查询字符串被解析为一系列词项(term)和运算符(operator)。
词项(term)可以是一个单词(如quick
或 brown
),也可以是一个用双引号括起来的短语(如"quick brown"
) - 它以相同的顺序搜索短语中的所有单词。
运算符允许你自定义搜索—可用选项如下所述。
可以在查询语法中指定要搜索的字段,下面是几个例子:
-
status
字段中包含单词active
:status:active
-
title
字段中包含单词quick
或brown
:title:(quick OR brown)
-
author
字段中包含精确匹配的短语"john smith"
:author:"John Smith"
-
first name
字段包含Alice
(注意,我们需要用反斜杠转义字段名称中的空格):first\ name:Alice
-
book.title
、book.content
或book.date
任意一个字段中包含单词quick
或brown
(注意,我们需要用反斜杠转义字段名称中的*
):book.\*:(quick OR brown)
-
字段
title
有任何非null的值(只要存在这个字段,即使其值是空字符串):_exists_:title
通配符搜索可以在单个词项上运行,使用 ?
替换单个字符,使用 *
替换零个或多个字符:
qu?ck bro*
请注意,通配符查询会占用大量内存,并且性能非常差——只要想想需要查询多少个词项才能匹配查询字符串 "a* b* c*"
。
为了提高效率,纯通配符 \*
被重写为 exists
查询。
因此,通配符 "field:*"
将匹配具有空值的文档,如下所示:
{ "field": "" }
... 如果字段缺失或设置了显式的 null 值,则 不 匹配,如下所示:
{ "field": null }
允许在单词的开头使用通配符(例如"*ing"
)的资源消耗特别大,因为需要检查索引中的所有词项,以防它们匹配。
通过将 allow_leading_wildcard
设置为 false
,可以禁用前置通配符。
只有部分分析链应用在字符级别的操作上。 例如,如果分析器既执行转小写又执行词干分析(提取),那么只会应用转小写操作:对一个缺少某些字母的单词执行词干分析是错误的。
通过将 analyze_wildcard
设置为true,将分析以 *
结尾的查询,通过确保前 N-1 个词元(token)的精确匹配和最后一个词元的前缀匹配,从不同的词元中构建 bool 查询。
通过将正则表达式模式用斜杠("/"
)包裹,可以将它们嵌入到查询字符串中:
name:/joh?n(ath[oa]n)/
正则表达式语法 中解释了支持的正则表达式语法。
allow_leading_wildcard
参数对正则表达式没有任何控制。
下面这个查询字符串将强制 Elasticsearch 访问索引中的每个词项:
/.*n/
慎用!
我们可以使用“模糊”运算符搜索与我们的搜索词项相似但又不完全相似的词项:
quikc~ brwn~ foks~
它使用 达梅劳-莱温斯坦距离 来查找最多有两个变化的所有词项,其变化包括单个字符的插入、删除或替换,或者两个相邻字符的位置调换。
默认的编辑距离是2
,但是编辑距离1
应该足以捕捉 80% 的人类拼写错误。
它可以指定为:
quikc~1
虽然短语查询(例如"john smith"
)希望所有词项的顺序完全相同,但 邻近查询(proximity query) 允许指定的词语相距更远或顺序不同。
与 模糊查询(fuzzy query) 可以指定单词中字符的最大编辑距离相同,邻近搜索允许我们指定短语中单词的最大编辑距离:
"fox quick"~5
字段中的文本越接近查询字符串中指定的原始顺序,该文档就被认为越相关。
与上面的示例查询相比,短语 "quick fox"
被认为比 "quick brown fox"
更相关。
可以为 date、numeric 或 string 字段指定范围。
包含范围用方括号[min TO max]
表示,不包含范围用花括号{min TO max}
表示。
-
2012年内的所有天数:
date:[2012-01-01 TO 2012-12-31]
-
数字 1 到 5:
count:[1 TO 5]
-
介于
alpha
和omega
之间的标签,但不包含alpha
和omega
: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)
查询字符串中范围的解析可能很复杂并且容易出错。
使用显式的 range
查询 要可靠得多。
使用增强(boost)运算符 ^
使一个词项比另一个更相关。
例如,如果我们想找到所有关于 fox
的文档,但是我们对 quick fox
特别感兴趣:
quick^2 fox
默认 boost
的值为 1,但可以是任何正浮点数。
boost
的值在 0 到 1 之间时会降低相关性。
boost
也可用于短语或分组:
"john smith"^2 (foo bar)^4
默认情况下,所有词项都是可选的,只要有一个词项匹配即可。
搜索 foo bar baz
将找到包含 foo
、bar
、baz
中的一个或多个的任何文档。
我们在上面已经讨论了 default_operator
,它允许你强制所有的词项都是必需的,但是也有一些布尔运算符可以在查询字符串本身中使用,以提供更多的控制。
首选运算符是 +
(该词项必须存在) 和 -
(该词项 必须不 存在)。所有其他词项都是可选的。
例如,下面这个查询:
quick brown +fox -news
说明:
-
fox
必须存在 -
news
必须不存在 -
quick
和brown
是可选的,但如果他们存在则会增加相关性
我们所熟悉的布尔运算符AND
、OR
和 NOT
(也写成 &&
、||
和 !
)也是受支持的,但要注意它们不遵守通常的优先规则,所以当多个运算符一起使用时,应该使用括号。
例如,前面的查询(即: quick brown +fox -news)可以重写为:
-
((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 字符串中保留的转义字符。
GET /twitter/_search { "query" : { "query_string" : { "query" : "kimchy\\!", "fields" : ["user"] } } }
保留字符有:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
未能正确转义这些特殊字符可能会导致语法错误,从而使查询无法运行。
<
和 >
根本不能进行转义。
防止他们试图创建范围查询的唯一方法是将他们从查询字符串中完全删除。
query_string
搜索不会返回 嵌套的(nested) 文档。
要搜索嵌套文档,请使用 nested
查询。
可以使用 fields
参数同时对多个字段执行 query_string
搜索。
对多个字段运行 query_string
查询的想法是将每个查询词项扩展为一个 OR 子句,如下所示:
field1:query_term OR field2:query_term | ...
例如,这个查询
GET /_search { "query": { "query_string" : { "fields" : ["content", "name"], "query" : "this AND that" } } }
与下面这个查询匹配相同的词:
GET /_search { "query": { "query_string": { "query": "(content:this OR name:this) AND (content:that OR name:that)" } } }
由于几个查询是从单个搜索词项中生成的,所以使用带有 tie_breaker
的 dis_max
查询自动完成对它们的组合。
例如(使用符号 ^5
将 name
增加 5):
GET /_search { "query": { "query_string" : { "fields" : ["content", "name^5"], "query" : "this AND that OR thus", "tie_breaker" : 0 } } }
简单通配符也可以用于“在”文档指定的内部元素中搜索。
例如,如果有一个包含多个字段的 city
对象(或包含几个字段的内部对象),则可以自动搜索所有"city"字段:
GET /_search { "query": { "query_string" : { "fields" : ["city.*"], "query" : "this AND that OR thus" } } }
另一个选项是在查询字符串本身中提供通配符字段搜索(正确转义 *
标志),例如:city.\*:something
:
GET /_search { "query": { "query_string" : { "query" : "city.\\*:(this AND that OR thus)" } } }
由于 \
(反斜杠)是 json 字符串中的一个特殊字符,因此需要转义,因此在上面的 query_string
中有两个反斜杠。
fields 参数还可以包括基于模式的字段名,允许自动展开到相关字段(包括动态引入的字段)。例如:
GET /_search { "query": { "query_string" : { "fields" : ["content", "name.*^5"], "query" : "this AND that OR thus" } } }
当对多个字段运行 query_string
查询时,支持下列附加参数。
-
type
-
(可选, string) 确定查询如何对文档进行匹配和评分。有效值有:
-
best_fields
(默认) -
查找与任何字段匹配的文档,并使用任何匹配字段中的最高的
_score
。 参见best_fields
。 -
bool_prefix
-
在每个字段上创建
match_bool_prefix
查询,并组合每个字段的_score
。 参见bool_prefix
。 -
cross_fields
-
用相同的
analyzer
处理字段,就好像它们是一个大字段。 在 任何 字段中查找每个单词。 参见cross_fields
。 -
most_fields
-
查找与任何字段匹配的文档,并合并每个字段的
_score
。参见most_fields
。 -
phrase
-
See
phrase
andphrase_prefix
. 对每个字段运行match_phrase
查询,并使用最佳字段(best field)的_score
。 参见phrase
和phrase_prefix
。 -
phrase_prefix
-
对每个字段运行
match_phrase_prefix
查询,并使用最佳字段(best field)的_score
。 参见phrase
和phrase_prefix
。
注意:根据
type
的值,multi_match
可能有额外的顶级参数。 -
query_string
查询支持 synonym_graph 词元过滤器(token filter)的多词项同义词扩展。
当使用该过滤器时,解析器将为每个多词项同义词创建一个短语查询。
例如,同义词 ny, new york
将产生:
(ny OR ("new york"))
还可以用"逻辑与"匹配多个词项同义词代替:
GET /_search { "query": { "query_string" : { "default_field": "title", "query" : "ny city", "auto_generate_synonyms_phrase_query" : false } } }
上面的示例创建了一个bool查询:
(ny OR (new AND york)) city
它将文档与词项 ny
或 逻辑与new AND york
相匹配。
默认情况下,参数 auto_generate_synonyms_phrase_query
设置为 true
。
query_string
根据每个运算符拆分查询,从而为整个输入创建布尔查询。
可以使用minimum_should_match
来控制结果查询中应该匹配的“should”子句的数量。
GET /_search { "query": { "query_string": { "fields": [ "title" ], "query": "this that thus", "minimum_should_match": 2 } } }
上面的例子创建了一个bool查询:
(title:this title:that title:thus)~2
它将返回单个字段title
与至少this
、that
或 thus
中的2个词项匹配的文档。
GET /_search { "query": { "query_string": { "fields": [ "title", "content" ], "query": "this that thus", "minimum_should_match": 2 } } }
上面的例子创建了一个bool查询:
((content:this content:that content:thus) | (title:this title:that title:thus))
它使用"逻辑或"最大限度的通过title
和content
字段去匹配文档。
这里无法应用minimum_should_match
参数。
GET /_search { "query": { "query_string": { "fields": [ "title", "content" ], "query": "this OR that OR thus", "minimum_should_match": 2 } } }
添加显式运算符(OR
)强制每个词项被视为一个单独的子句。
上面的例子创建了一个bool查询:
((content:this | title:this) (content:that | title:that) (content:thus | title:thus))~2
这使文档至少与三个“should”子句中的两个匹配,每个子句都是由每个词项的字段上的最大"逻辑或"构成的。
字段type
的值为cross_fields
时,对在分析输入时使用了相同分析器的字段进行分组。
GET /_search { "query": { "query_string": { "fields": [ "title", "content" ], "query": "this OR that OR thus", "type": "cross_fields", "minimum_should_match": 2 } } }
上面的例子创建了一个bool查询:
(blended(terms:[field2:this, field1:this]) blended(terms:[field2:that, field1:that]) blended(terms:[field2:thus, field1:thus]))~2
这将匹配与三个词项混合(blended)查询中的至少两个匹配的文档。