此查询使用语法根据运算符(例如 AND
或 NOT
)解析和拆分提供的查询字符串。 查询然后在返回匹配文档之前独立分析每个拆分文本。
可以使用 query_string
查询来创建包含通配符、跨多个字段的搜索等的复杂搜索。 虽然用途广泛,但查询是严格的,如果查询字符串包含任何无效语法,则返回错误。
如果您不需要支持查询语法,请考虑使用match
查询。 如果您需要查询语法的功能,请使用不那么严格的 simple_query_string
查询。
需要详细了解每个Query string query细节,可以参考官网API:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html?baymax=rec&rogue=pop-1&elektra=docs
总结一下其中比较重要的几点:
Query string syntax
查询字符串被解析为一系列terms
和operators
。 一个term
可以是单个词 --- quick
或 brown
--- 或被双引号括起来的词组 --- “quick brown” --- ,它以相同的顺序搜索词组中的所有词。
运算符允许您自定义搜索 -- 可用选项如下所述。
Field names
可以在查询语法中指定要搜索的字段:
- where the
status
field containsactive
status:active
- where the
title
field containsquick
orbrown
title:(quick OR brown)
- where the author field contains the exact phrase "john smith"
author:"John Smith"
- where the
first name
field containsAlice
(note how we need to escape the space with a backslash)
first\ name:Alice
- where any of the fields
book.title
,book.content
orbook.date
containsquick
orbrown
(note how we need to escape the*
with a backslash):
book.\*:(quick OR brown)
- where the field
title
has any non-null value:
_exists_:title
Wildcards
通配符搜索可以使用 ? 替换单个字符,* 替换零个或多个字符:
qu?ck bro*
请注意,通配符查询会占用大量内存并且性能非常差 — 只需考虑需要查询多少个terms
才能匹配查询字符串“a* b* c*”
.
允许在单词的开头使用通配符(例如“*ing”
)特别heavy,因为需要检查索引中的所有术语,以防它们匹配。 可以通过将allow_leading_wildcard
设置为 false
来禁用前导通配符。
Regular expressions
正则表达式模式可以通过将它们包装在正斜杠(“/”)
中来嵌入到查询字符串中:
name:/joh?n(ath[oa]n)/
allow_leading_wildcard
参数对正则表达式没有任何控制。 如下查询字符串将强制 Elasticsearch 访问索引中的每个term
:/.*n/
,谨慎使用!
Fuzziness
我们可以使用“模糊”运算符搜索与我们的搜索词相似但不完全相同的词:quikc~ brwn~ foks~
。
默认的编辑距离是2
,但1
的编辑距离应该足以捕获所有人类拼写错误的80%。 它可以指定为:
quikc~1
不支持混合使用模糊和通配符运算符。 混合时,不应用其中一个运算符。 例如,您可以搜索 app~1(模糊)或 app(通配符),但搜索 app~1 不应用模糊运算符 (~1)。
Proximity searches
虽然短语查询(例如“john smith”
)期望所有词条的顺序完全相同,但邻近查询允许指定的词相距更远或以不同的顺序排列。 与模糊查询可以指定单词中字符的最大编辑距离相同,邻近搜索允许我们指定短语中单词的最大编辑距离:
“fox quick”~5
字段中的文本与查询字符串中指定的原始顺序越接近,则认为该文档越相关。 与上面的示例查询相比,短语“quick fox”
将被认为比“quick brown fox”
更相关。
Ranges
可以为日期、数字或字符串字段指定范围。 包含范围用方括号 [min TO max]
指定,不包含范围用大括号 {min TO max}
指定。
- All days in 2012:
date:[2012-01-01 TO 2012-12-31]
- Numbers 1..5
count:[1 TO 5]
- Tags between alpha and omega, excluding alpha and omega:
tag:{alpha TO omega}
- Numbers from 10 upwards
count:[10 TO *]
- Dates before 2012
date:{* TO 2012-01-01}
要将上限和下限与简化语法结合,您需要使用 AND 运算符连接两个子句:
age:(>=10 AND <20)
age:(+>=10 +<20)
查询字符串中范围的解析可能很复杂且容易出错。 使用显式range
查询要可靠得多。
Boolean operators
首选运算符是 +
(该术语必须存在)和 -
(该术语不得存在)。 所有其他条款都是可选的。 例如,这个查询:
quick brown +fox -news
语义是:
-
fox
must be present -
news
must not be present -
quick
andbrown
are optional — their presence increases the relevance
也支持相似的布尔运算符 AND
、OR
和 NOT
(也写为 &&
、||
和 !
),但要注意它们不遵守通常的优先规则,因此当多个运算符一起使用时应使用括号。 例如,前面的查询可以重写为:
((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" }
}
}
Grouping
多个术语或子句可以用括号组合在一起,形成子查询:
(quick OR brown) AND fox
组可用于定位特定字段,或提升子查询的结果:
status:(active OR pending) title:(full text search)^2
Reserved characters
如果您需要使用在查询本身中用作运算符的任何字符(而不是用作运算符),则应使用前导反斜杠对它们进行转义。 例如,要搜索 (1+1)=2
,您需要将查询写为 \(1\+1\)\=2
。 请求正文使用 JSON 时,需要两个前面的反斜杠 (\\
); 反斜杠是 JSON 字符串中的保留转义字符。
GET /my-index-000001/_search
{
"query" : {
"query_string" : {
"query" : "kimchy\\!",
"fields" : ["user.id"]
}
}
}
需要转义的字符有:
+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
未能正确转义这些特殊字符可能会导致语法错误,从而阻止您的查询运行。
< and >
根本无法转义。 阻止它们尝试创建范围查询的唯一方法是将它们从查询字符串中完全删除。
Whitespaces and empty queries
空格不被视为运算符。如果查询字符串为空或仅包含空格,则查询将产生一个空结果集。
Avoid using the query_string
query for nested documents
query_string
searches do not return nested documents. To search nested documents, use the nested
query.
Search multiple fields
您可以使用 fields
参数跨多个字段执行 query_string
搜索。
对多个字段运行 query_string
查询的想法是将每个查询词扩展为一个 OR 子句,如下所示:
field1:query_term OR field2:query_term | ...
For example, the following query
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)"
}
}
}
简单的通配符也可用于搜索文档的“内部”特定内部元素。 例如,如果我们有一个带有多个字段的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)"
}
}
}