假如产品又给你提了需求,优化系统的搜索框,这次按照类似kibana的搜索框优化,你要怎么做呢?本篇文章将介绍Es解决这个需求的相关API。
1.combined fields
combined_fields 查询支持搜索多个文本字段,就好像他们的内容已经被索引到一个组合字段中一样。它采用以Term为中心的查询视图:首先他会将查询内容拆分成多个Term,然后再每一个字段中查找每一个Term。当匹配可能跨越多个文本字段时,这个查询十分适用。
For Example:
GET order/_search
{
"query": {
"combined_fields" : {
"query": "database systems",
"fields": [ "id", "name", "order_no"],
"operator": "and"
}
}
}
组合字段查询基于BM25F公式,采用了原则性的评分方法。在对匹配字段进行评分时,查询会合并字段之间的Term和集合统计信息。这使它能够对每一次匹配进行评分,就好像指定的字段已被索引到一个单独的组合字段中一样。
字段数量限制:一次可以查询的字段数量是有限制的。它由
indices.query.bool.max_clause_count搜索设置定义,默认值为1024。
可以使用插入符号(^)增强各个字段的打分:
GET order/_search
{
"query": {
"combined_fields" : {
"query" : "distributed consensus",
"fields" : [ "name^2", "id" ]
}
}
}
字段增强是根据组合字段模型来理解的,比如,name字段的提升值为2,当计算得分的时候,就好像name中的每个Term在合成字段中出现两次一样。
字段增强支持小数,但是前提是增强后的值大于等于1.0。
ombined_fields 查询的高级参数设置:
| 参数 | 说明 |
|---|---|
| fields | (必需,字符串数组)要搜索的字段列表。允许使用字段通配符模式。只支持文本字段,并且它们必须都具有相同的搜索分析器。 |
| query | (必需,字符串)要在提供的<fields>中搜索的文本。combined_fields 查询在执行搜索之前分析所提供的文本。 |
| auto_generate_synonyms_phrase_query | (可选,布尔值)如果为true,则会自动为多Term同义词创建匹配短语查询。默认为true。 |
| operator | (可选,字符串)用于组合查询值中的文本的布尔逻辑。有效值为: |
| or,默认值,比如查询 "this are" 被组合成 "this" OR "are" 。 | |
| and,比如查询 "this are" 被组合成 "this" AND "are" 。 | |
| minimum_should_match | (可选,字符串)要返回的文档必须匹配的最小子句数。 |
| zero_terms_query | (可选,字符串)如果分词器删除所有标记(例如使用停止筛选器时),是否不返回任何文档。有效值为: |
| none,默认值,不会返回任何文档 | |
| all,返回所有的文档。 |
与 multi_match 查询的比较:
combined_fields 查询提供了一种跨多个文本字段进行匹配和评分的原则性方法。为了支持这一点,它要求所有字段都具有相同的搜索分析器。
如果想要一个处理不同类型字段(如关键字或数字)的单一查询,那么 multi_match 查询可能更适合。它同时支持文本字段和非文本字段,并接受每一个字段的文本分词器不同。
multi_match 主要的两种模式 best_fields 和 most_fields 采用以字段为中心的查询视图。相反,combined_fields 是以Term为中心的:operator 和 minimum_should_match 是按Term而不是按字段应用的。
GET order/_search
{
"query": {
"combined_fields" : {
"query": "database systems",
"fields": [ "name", "id"],
"operator": "and"
}
}
}
上面的SQL,会被大概解析成:
+(combined("database", fields:["name" "id"]))
+(combined("systems", fields:["name", "id"]))
或者说,每一个Term必须至少出现在一个字段中,文档才能被匹配。
2. Query string
query_string 查询基于提供的查询字符串进行查询,并使用一个具有严格语法的解析器。这意味着 query_string 查询对提供的查询字符串采用一种严格的语法,并按照操作符(如AND或NOT)进行解析和拆分,并独立分析每个拆分的文本,然后返回匹配的文档。
你可以使用 query_string 查询创建一个复杂的搜索,包括通配符字符、跨多个字段进行搜索等。然而,query_string 查询的语法是严格的,如果查询字符串中包含任何无效的语法,则会返回错误。
由于
query_string查询对无效的语法返回错误,不建议在搜索框中使用它。如果你不需要支持查询语法,可以使用match查询。如果你需要查询语法的功能,可以考虑使用simple_query_string查询,它比query_string查询更宽松。
当使用query_string查询进行搜索时,括号内的短语"(new york city) OR (big apple)"会被拆分为两个部分,并且分析器会独立处理每个部分。由于查询语法不使用空格作为操作符,所以短语"new york city"会被整个作为一个Term进行处理。
GET order/_search
{
"query": {
"query_string": {
"query": "(new york city) OR (big apple)",
"default_field": "address"
}
}
}
以下是Elasticsearch 7.x版本中query_string查询的所有参数及其说明:
| 参数名 | 说明 |
|---|---|
| query | 要执行的查询字符串。 |
| default_field | 指定默认的字段名,当查询字符串中没有指定字段时将使用该字段进行搜索。 |
| fields | 指定要搜索的字段列表。 |
| default_operator | 指定字段之间的默认逻辑操作符。可选值为"AND"和"OR"。默认为"OR"。 |
| analyzer | 指定用于分析查询字符串的分析器。 |
| allow_leading_wildcard | 指定是否允许在查询字符串的开头使用通配符。默认为true。 |
| enable_position_increments | 指定是否启用位置增量。默认为true。 |
| fuzzy_max_expansions | 指定模糊匹配的最大扩展数。默认为50。 |
| fuzzy_prefix_length | 指定模糊匹配的前缀长度。默认为0。 |
| fuzzy_rewrite | 指定模糊匹配的重写方法。可选值为"constant_score_auto"、"scoring_boolean"、"constant_score_boolean"和"top_terms_N"(其中N是一个整数)。 |
| fuzzy_transpositions | 指定是否允许交换相邻字符进行模糊匹配。默认为true。 |
| lenient | 指定是否允许宽松模式,允许解析并忽略格式错误的查询字符串。默认为false。 |
| locale | 指定用于解析数字、日期和日期时间的区域设置。 |
| minimum_should_match | 指定bool查询中至少应匹配的子句数量。 |
| quote_field_suffix | 指定字段名后缀,用于引用短语查询。默认为".exact"。 |
| split_on_whitespace | 指定是否在空格处拆分查询字符串。默认为true。 |
| time_zone | 指定用于解析日期和日期时间的时区。 |
| analyze_wildcard | 指定是否在通配符查询中应用分析器。默认为false。 |
| max_determinized_states | 指定正则表达式查询的最大确定状态数。默认为10000。 |
当使用日期数学计算,例如now/d,时,time_zone参数会将计算结果转换为指定时区的对应时间。这意味着在进行日期数学计算时,time_zone参数可以用来调整结果的时区。然而,对于now本身的值,它始终表示的是UTC时间下的当前系统时间,并不受time_zone参数的影响。
3. Query String 语法
query string 语法是由查询字符串(Query string)和搜索API中的 q query string 参数使用的一种“迷你语言”(mini-language)。
输入内容会被解析成一系列的Term和操作符。一个Term可以是一个单词,比如"quick"或"brown",或者是一个用双引号括起来的短语,比如"quick brown",这样的查询将搜索短语中所有的单词,并且按照相同的顺序进行匹配。
3.1 Field names
| 查询条件 | 查询字符串语法 |
|---|---|
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字段存在非空值 | _exists_:title |
3.2 Wildcards
通配符搜索可以在单个术语上执行,使用?来代替单个字符,使用 *来代替零个或多个字符:例如,"qu?ck bro*"表示匹配以"qu"开头,后面跟着一个字符(可以是任意字符),然后是"ck",最后以"bro"开头的任意后缀。
需要注意的是,通配符查询可能会消耗大量内存并且性能很差。想象一下,要匹配查询字符串"a* b* c*"需要查询多少个术语,这样的查询可能会非常耗费资源并且执行效率很低。因此,在使用通配符查询时需要谨慎使用,特别是对于大量数据和复杂查询字符串的情况下。如果可能的话,建议使用其他更高效的查询方式来避免潜在的性能问题。
为了提高查询效率,纯通配符(*)会被重写为exists查询。因此,通配符"field:*"会匹配包含空值的文档,例如以下示例:
{
"field": ""
}
但如果字段缺失或者显式设置为null值,通配符查询将不会匹配,例如以下示例:
{
"field": null
}
换句话说,当使用纯通配符查询时,它会检查字段是否存在并且非空,而不仅仅是匹配字段的任意值。因此,纯通配符查询不会匹配字段缺失或者显式设置为null值的文档。这个特性可以帮助在查询时精确控制通配符的行为,确保只匹配具有非空值的字段。
允许在单词的开头使用通配符(例如"*ing")会导致查询的负载增加,因为需要检查索引中的所有术语,以防止它们与通配符匹配。由于需要遍历整个索引,这种以通配符开头的查询开销较大。
为了控制查询的性能,可以通过将
allow_leading_wildcard设置为false来禁用以通配符开头的查询。这样一来,查询将不再允许在单词开头使用通配符,从而减少了查询的开销。禁用以通配符开头的查询可以提高查询的性能,特别是在涉及大量术语和索引数据时。但需要注意,禁用此功能可能会影响某些特定查询的准确性和灵活性。因此,在使用时需要权衡性能和查询需求。
对于包含通配符的查询,在分析链中只会应用字符级别的操作。例如,如果分析器同时执行小写转换和词干提取,那么只会应用小写转换操作,不会进行词干提取操作。因为对于缺少某些字母的单词进行词干提取是不正确的。
通过将analyze_wildcard参数设置为true,以通配符(*)结尾的查询将会被分析,并且通过在前N-1个标记上确保精确匹配,并在最后一个标记上进行前缀匹配来构建布尔查询。
换句话说,设置analyze_wildcard为true后,查询将被分析并将不同的标记构建成布尔查询。对于前N-1个标记,确保精确匹配,而对于最后一个标记,则进行前缀匹配。这个设置可以使通配符查询更加灵活,能够在查询的不完整术语中进行前缀匹配。这在需要搜索具有共同前缀的术语时非常有用。
3.3 Regular expressions
正则表达式模式可以通过使用斜杠 ("/") 将其包裹在查询字符串中来嵌入。例如,使用正则表达式模式来搜索名字中可能的变体,可以编写如下的查询字符串:
name:/joh?n(ath[oa]n)/
在上述查询中,使用了正则表达式模式来匹配名字可能的变体,例如 "johnathan" 或 "jonathan"。通过使用正则表达式模式,可以实现更复杂和灵活的匹配规则,以满足特定的查询需求。
allow_leading_wildcard 参数不对正则表达式起作用。 例如,以下的查询字符串会强制Elasticsearch访问索引中的每个术语:
/.*n/
这个正则表达式模式以任意字符(.)和零个或多个字符(*)开头,然后是字母"n"。由于通配符"."和"*"的使用,这个查询字符串会匹配任何以字母"n"结尾的词,包括索引中的所有术语。然而,由于查询字符串中使用了正则表达式模式,而不是通配符,所以allow_leading_wildcard参数对其没有控制作用。
这样的查询会导致Elasticsearch访问索引中的每个术语,这可能会非常耗费资源和时间。因此,在使用这样的正则表达式查询时需要谨慎,确保对查询的性能影响有所了解。
3.4 Fuzziness
可以使用~运算符来运行模糊查询:
quikc~ brwn~ foks~
在这些查询中,查询字符串会被规范化。如果存在,只会应用分析器中的特定过滤器。这个查询使用Damerau-Levenshtein距离来找到最多两次变化(change)的所有术语。其中变化可以是插入、删除或替换单个字符,或者是两个相邻字符的转置。默认的编辑距离是2,但编辑距离为1就足以捕捉到80%的人类拼写错误。可以通过以下方式指定编辑距离:
quikc~1
这样的查询可以帮助你在搜索时容忍一定程度的拼写错误或变体形式。通过设置合适的编辑距离,可以在模糊查询中更好地匹配目标词汇。
不支持混合使用模糊查询(fuzzy)和通配符查询(wildcard)。当混合使用时,其中一个操作符将不起作用。例如,你可以搜索app~1(模糊查询)或app*(通配符查询),但是搜索app*~1不会应用模糊操作符(~1)。
3.5 Proximity searches
与短语查询(例如 "john smith")要求所有术语按照完全相同的顺序出现不同,接近查询(proximity query)允许指定的词之间的距离更远或顺序不同。与模糊查询可以为单词中的字符指定最大编辑距离一样,接近搜索允许我们指定短语中单词的最大编辑距离。例如,使用接近搜索可以指定词语之间的最大编辑距离为5:
"fox quick"~5
文本在字段中与查询字符串中指定的原始顺序越接近,就认为该文档越相关。与上面的示例查询相比,短语 "quick fox" 会被认为比 "quick brown fox" 更相关。这种接近搜索可以在需要容忍单词之间一定程度距离或顺序变化的情况下使用,以扩展查询的匹配范围。
3.6 Ranges
范围查询可以针对日期、数值或字符串字段进行指定。使用方括号 [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} |
| 只有一侧范围限制的情况 | |
| - 年龄大于10 | age:>10 |
| - 年龄大于等于10 | age:>=10 |
| - 年龄小于10 | age:<10 |
| - 年龄小于等于10 | age:<=10 |
| 同时指定上限和下限的情况 | |
| - 年龄在10到20之间 | age:(>=10 AND <20) |
| - 年龄在10到20之间(另一种写法) | age:(+>=10 +<20) |
使用显式的范围查询语法可以更稳定和可靠地定义范围查询条件,而不依赖于
query string的解析机制。
3.7 Boosting
使用 boost 运算符 ^ 可以使一个词比另一个词更加相关。例如,如果我们想要找到所有关于 "foxes" 的文档,但对 "quick foxes" 特别感兴趣:
quick^2 fox
默认的 boost 值为 1,但可以是任何正的浮点数。0 到 1 之间的 boost 值会降低相关性。
Boosts 也可以应用于短语或组:
"john smith"^2 (foo bar)^4
以上示例中,"john smith"^2 表示对包含短语 "john smith" 的文档进行更高的相关性加权,而 (foo bar)^4 表示对括号内的词组 "foo bar" 进行更高的相关性加权。通过使用 boost 运算符,我们可以调整文档的相关性得分,使某些词、短语或组在搜索结果中更加突出和重要。
3.8 Boolean operators
默认情况下,所有的词项都是可选的,只要其中一个词项匹配即可。例如,在搜索 foo bar baz 时,会找到包含 foo、bar 或 baz 中的一个或多个词的任何文档。我们已经在上面讨论了默认运算符 default_operator,它允许您强制要求所有词项都是必需的,但在 query string 本身中还可以使用布尔运算符来提供更多的控制。
首选的运算符是 +(此词项必须存在)和 -(此词项必须不存在)。其他所有词项都是可选的。例如,以下查询:
quick brown +fox -news
表示:
- fox 必须存在
- news 必须不存在
- quick 和 brown 是可选的 - 它们的存在会增加相关性
布尔运算符 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"
}
}
}
3.9 Grouping
多个词项或子句可以用括号分组,形成子查询:
(quick OR brown) AND fox
分组可以用于针对特定字段,或者提升子查询的结果:
status:(active OR pending) title:(full text search)^2
这里提到了使用括号可以将多个词项或子句组合在一起形成子查询。括号可以用于指定特定字段的条件,也可以用于提升子查询的结果。第一个例子中,查询要求结果中包含 quick 或 brown,并且同时包含 fox。第二个例子中,查询要求 status 字段包含 active 或 pending,同时 title 字段包含 "full text search",并对 title 字段的子查询结果进行了加权处理。
3.10 Reserved characters
如果你的查询中需要使用那些作为操作符的字符本身(而不是作为操作符),那么你应该在它们之前加上一个反斜杠进行转义。例如,如果要搜索 (1+1)=2,你需要将查询写为 1\+1=2。当在请求体中使用 JSON 格式时,需要使用两个反斜杠(\)进行转义;在 JSON 字符串中,反斜杠是一个保留的转义字符。
GET /order/_search
{
"query" : {
"query_string" : {
"query" : "kimchy\\!",
"fields" : ["name"]
}
}
}
这些特殊字符是保留字符:
+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /。如果没有正确转义这些特殊字符,可能会导致语法错误,从而阻止你的查询运行。
<和>无法进行转义。防止它们尝试创建范围查询的唯一方法是完全从查询字符串中删除它们。
3.11 Whitespaces and empty queries
空格不被视为操作符。如果查询字符串为空或只包含空格,则查询将返回空的结果集。
避免在嵌套文档中使用 query string 查询。
query_string查询不返回嵌套文档。要搜索嵌套文档,请使用nested查询。
3.12 Search multiple fields
你可以使用fields参数在多个字段上执行 query_string 查询。在多个字段上运行 query_string 查询的思路是将每个查询词扩展为一个类似于下面的OR子句:
field1:query_term OR field2:query_term | ...
For Example:
GET order/_search
{
"query": {
"query_string": {
"fields": [ "id", "name" ],
"query": "this AND that"
}
}
}
类似于:
GET order/_search
{
"query": {
"query_string": {
"query": "(id:this OR name:this) AND (id:that OR name:that)"
}
}
}
由于从每个单独的搜索词生成了多个查询,因此将它们组合在一起是使用 dis_max 查询和 tie_breaker 自动完成的。例如(使用^5符号将名称提升了5倍):
GET order/_search
{
"query": {
"query_string" : {
"fields" : ["id", "name^5"],
"query" : "this AND that OR thus",
"tie_breaker" : 0
}
}
}
简单通配符也可以用于在文档的特定内部元素中进行搜索。例如,如果我们有一个包含多个字段(或带有字段的内部对象)的city对象,我们可以自动在所有"city"字段上进行搜索:
GET order/_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" : ["id", "name.*^5"],
"query" : "this AND that OR thus"
}
}
}
在对多个字段运行 query_string 查询时,还支持以下额外的参数。
| type | Description |
|---|---|
| best_fields | 找到与任何字段匹配的文档,并使用所有匹配字段中最高的 _score 值。详见 best_fields。 |
| bool_prefix | 在每个字段上创建 match_bool_prefix 查询,并将每个字段的 _score 值进行合并。详见 bool_prefix。 |
| cross_fields | 将具有相同分析器的字段视为一个大字段,查找任何字段中的每个词。详见 cross_fields。 |
| most_fields | 找到与任何字段匹配的文档,并将每个字段的 _score 值进行合并。详见 most_fields。 |
| phrase | 在每个字段上运行 match_phrase 查询,并使用最佳字段的 _score 值。详见 phrase 和 phrase_prefix。 |
| phrase_prefix | 在每个字段上运行 match_phrase_prefix 查询,并使用最佳字段的 _score 值。详见 phrase 和 phrase_prefix。 |
3.13 minimum_should_match 是如何工作的?
query_string 会根据每个运算符将查询拆分,以创建整个输入的布尔查询。您可以使用 minimum_should_match 参数来控制在生成的查询中应匹配多少个"should"子句。
GET order/_search
{
"query": {
"query_string": {
"fields": [
"name"
],
"query": "this that thus",
"minimum_should_match": 2
}
}
}
上面的SQL创建了一个布尔查询:
(name:this name:that name:thus)~2
它匹配在单个字段name中至少有两个词this、that或thus的文档。
3.14 minimum_should_match 如何在多字段中工作的?
GET order/_search
{
"query": {
"query_string": {
"fields": [
"name",
"description"
],
"query": "this that thus",
"minimum_should_match": 2
}
}
}
上述示例创建了一个布尔查询:
((name:this name:that name:thus) | (description:this description:that description:thus))
该查询使用字段"name"和字段"description"进行最大分离匹配(disjunction max)。在这种情况下,无法应用 minimum_should_match 参数。该查询将匹配具有在"name"字段和"description"字段中的任意一个中出现的术语("this"、"that"和"thus")。最大分离匹配操作符(|)会考虑两个子查询中的最高分数。
由于 minimum_should_match 参数在单个查询的术语或子句级别起作用,而不是跨多个子查询,因此在给定的示例中,无法直接应用 minimum_should_match 参数。如果要控制在每个字段内应匹配的最小术语数,请单独将 minimum_should_match 参数应用于每个子查询。
GET order/_search
{
"query": {
"query_string": {
"fields": [
"description",
"name"
],
"query": "this OR that OR thus",
"minimum_should_match": 2
}
}
}
添加显式操作符会使每个术语被视为一个单独的子句。上述示例创建了一个布尔查询:
((description:this | name:this) (description:that | name:that) (description:thus | name:thus))~2
该查询匹配至少两个“should”子句的文档,每个子句由每个术语的字段的最大分离匹配组成。
4.Simple query string
4.1 API & Params
该查询根据提供的查询字符串返回文档,使用一个具有有限但容错性的语法解析器。该查询使用简单的语法来解析并根据特殊操作符将提供的查询字符串拆分为Term。然后,该查询独立分析每个Term,然后返回匹配的文档。虽然它的语法比 query_string 查询更加有限,但simple_query_string查询不会对无效的语法返回错误。相反,它会忽略查询字符串中的任何无效部分。
For Example:
GET order/_search
{
"query": {
"simple_query_string" : {
"query": ""fried eggs" +(eggplant | potato) -frittata",
"fields": ["title^5", "body"],
"default_operator": "and"
}
}
}
| 参数 | 描述 |
|---|---|
| query | (必填,字符串) 要解析并用于搜索的查询字符串。参见简单查询字符串语法。 |
| fields | (可选,字符串数组) 要搜索的字段数组。 |
| default_operator | (可选,字符串) 如果未指定运算符,用于解释查询字符串中的文本的默认布尔逻辑。有效值包括: |
| OR (默认值) - 例如,查询字符串 "匈牙利的首都" 被解释为 "首都 OR 匈牙利"。 | |
| AND - 例如,查询字符串 "匈牙利的首都" 被解释为 "首都 AND 匈牙利"。 | |
| all_fields | [6.0.0] 在6.0.0版中弃用。将 fields 设置为 *。 (可选,布尔值) 如果为 true,则搜索索引字段映射中的所有可搜索字段。 |
| analyze_wildcard | (可选,布尔值) 如果为 true,则查询字符串中的通配符项将尝试进行分析。默认为 false。 |
| analyzer | (可选,字符串) 用于将查询字符串中的文本转换为标记的分析器。默认为与 default_field 映射的索引时间分析器。如果没有映射分析器,则使用索引的默认分析器。 |
| auto_generate_synonyms_phrase_query | (可选,布尔值) 如果为 true,则解析器为每个多位置标记创建一个 match_phrase 查询。默认为 true。例如,请参见多位置标记。 |
| flags | (可选,字符串) 简单查询字符串语法的已启用运算符列表。默认为 ALL(所有运算符)。有关有效值,请参见限制运算符。 |
| fuzzy_max_expansions | (可选,整数) 对于模糊匹配,查询展开的最大项数。默认为 50。 |
| fuzzy_prefix_length | (可选,整数) 模糊匹配时保持不变的起始字符数。默认为 0。 |
| fuzzy_transpositions | (可选,布尔值) 如果为 true,则模糊匹配的编辑包括两个相邻字符的换位(ab → ba)。默认为 true。 |
| lenient | (可选,布尔值) 如果为 true,则忽略基于格式的错误,例如为数值字段提供文本值。默认为 false。 |
| minimum_should_match | (可选,字符串) 必须匹配的最小子句数以返回文档。有关有效值和更多信息,请参见 minimum_should_match 参数。 |
| quote_field_suffix | (可选,字符串) 在查询字符串中引用的文本后附加的后缀。您可以使用此后缀来使用不同的分析方法进行精确匹配。请参见混合精确搜索和词干处理。 |
对于fields字段:一次查询中可以查询的字段数量有限制。该限制由
indices.query.bool.max_clause_count搜索设置定义,默认值为 1024。
4.2 Simple query string 语法
simple_query_string 支持以下操作运算符:
| Operator | Meaning |
|---|---|
| + | 表示 AND 操作 |
| | | 表示 OR 操作 |
| - | 取反单个词元 |
| " | 将一系列词元括在一起,表示短语搜索 |
| * | 在词项末尾表示前缀查询 |
| ( and ) | 表示优先级 |
| ~N | 在单词后表示编辑距离(模糊度) |
| ~N | 在短语后表示可接受的相邻位置的数量 |
要直接使用这些字符中的任何一个,需要在它前面加上反斜杠(\)进行转义。这些运算符的行为可能会根据 default_operator 的值而有所不同。
GET order/_search
{
"query": {
"simple_query_string": {
"fields": [ "name" ],
"query": "foo bar -baz"
}
}
}
这个搜索旨在仅返回包含 "foo" 或 "bar" 且不包含 "baz" 的文档。然而,由于默认的 default_operator 是 OR,这个搜索实际上返回了包含 "foo" 或 "bar" 的文档以及不包含 "baz" 的任何文档。为了按照预期返回文档,请将查询字符串更改为 foo bar +-baz。
4.3 Limit 运算符
您可以使用 flags 参数来限制支持的简单查询字符串语法的操作符。要显式地只启用特定的操作符,可以使用 | 分隔符。例如,flags 参数值为 OR|AND|PREFIX 将禁用除了 OR、AND 和 PREFIX 之外的所有操作符。
GET order/_search
{
"query": {
"simple_query_string": {
"query": "foo | bar + baz*",
"flags": "OR|AND|PREFIX"
}
}
}
flags 参数的有效值如下:
| 参数名 | 中文解释 |
|---|---|
| ALL | 启用所有可选的运算符。 |
| AND | 启用 + AND 运算符。 |
| ESCAPE | 启用 \ 作为转义字符。 |
| FUZZY | 启用 ~N 运算符,在单词后面,其中 N 是表示允许的匹配编辑距离的整数。请参阅模糊匹配。 |
| NEAR | 启用 ~N 运算符,在短语后面,其中 N 是允许匹配标记之间的最大位置数。与 SLOP 同义。 |
| NONE | 禁用所有运算符。 |
| NOT | 启用 - NOT 运算符。 |
| OR | 启用 | OR 运算符。 |
| PHRASE | 启用 " 引号运算符,用于搜索短语。 |
| PRECEDENCE | 启用 ( 和 ) 运算符以控制运算符优先级。 |
| PREFIX | 启用 * 前缀运算符。 |
| SLOP | 启用 ~N 运算符,在短语后面,其中 N 是允许匹配标记之间的最大位置数。与 NEAR 同义。 |
| WHITESPACE | 启用空格作为分隔符。 |
4.4 wildcard & boosted
fields 支持通配符。
GET /_search
{
"query": {
"simple_query_string" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ]
}
}
}
可以使用插入符(^)符号对单个字段进行加权(boost)操作。
GET /_search
{
"query": {
"simple_query_string" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ]
}
}
}
4.5 Multi-position tokens
Multi-position tokens 指的是在分词过程中生成的占据多个位置的单词。在某些情况下,一个单词可能会被分为多个词元,并且这些词元在文档中占据不同的位置。例如,对于一个包含多个单词的短语,每个单词可能被分为多个词元,并且这些词元在短语中占据不同的位置。
在使用查询时,如果设置了 auto_generate_synonyms_phrase_query 参数为 true,则对于占据多个位置的词元,解析器会为每个词元创建一个 match_phrase 查询。这样可以确保查询与包含这些词元的文档匹配。所以,Multi-position tokens 指的是在分词过程中占据多个位置的词元。
For Example,解析器会为多词元同义词“ny, new york”创建一个 match_phrase 查询:
(ny OR ("new york"))
如果希望使用AND连接符匹配占据多个位置的词元,可以将 auto_generate_synonyms_phrase_query 设置为false。
GET /_search
{
"query": {
"simple_query_string": {
"query": "ny city",
"auto_generate_synonyms_phrase_query": false
}
}
}
对于上面的SQL,解析器创建了以下布尔查询:
(ny OR (new AND york)) city)
这个布尔查询匹配包含词项“ny”或连接词“new AND york”的文档。
5. For More
例如intervals query这样的查询,由于篇幅原因,本文并未提到。如果想要了解更多全文搜索的API,请查阅官方文档。