# 查询语句查询

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html)（修改该链接为官网对应的链接）

译文链接 :[http://www.apache.wiki/pages/viewpage.action?pageId=4816898](http://www.apache.wiki/pages/viewpage.action?pageId=4882547)（修改该链接为 ApacheCN 对应的译文链接）

贡献者 : @羊两头

## 查询语句查询

使用查询解析器为了解析其内容的查询。 这里是一个例子：

```
GET /_search
{
    "query": {
        "query_string" : {
            "default_field" : "content",
            "query" : "this AND that OR thus"
        }
    }
}

```

query_string以下几个重要参数：

| 参数 | 描述 |
| `query` | 要解析的实际查询。 请参阅查询字符串语法。 |
| `default_field` | 如果未指定前缀字段，则为查询字词的默认字段。 默认为index.query.default_field索引设置，默认为_all。 |
| `default_operator` | 如果未指定显式运算符，则使用默认运算符。 例如，使用OR的默认运算符，匈牙利的查询资本将转换为OR匈牙利的资本OR，如果使用默认运算符AND，则相同的查询将转换为AND匈牙利的资本AND。 默认值为OR。 |
| `analyzer` | 用于分析查询字符串的分析器名称。 |
| `allow_leading_wildcard` | 设置时，*或？ 被允许作为第一个字符。 默认为true。 |
| `lowercase_expanded_terms` | 通配符，前缀，模糊和范围查询的条件是否自动降低或不降低（因为它们没有被分析）。 默认为true。 |
| `enable_position_increments` | 设置为true可在结果查询中启用位置增量。 默认为true。 |
| `fuzzy_max_expansions` | 控制模糊查询将扩展到的术语数。 默认值为50 |
| `fuzziness` | 设置模糊查询的模糊性。 默认为AUTO。 有关允许的设置，请参阅“Fuzzinessedit”一节. |
| `fuzzy_prefix_length` | 设置模糊查询的前缀长度。 默认值为0。 |
| `phrase_slop` | 设置短语的默认斜率。 如果为零，则需要精确的短语匹配。 默认值为0。 |
| `boost` | 设置查询的提升值。 默认为1.0。 |
| `analyze_wildcard` | 默认情况下，不分析查询字符串中的通配符术语。 将此值设置为true，将尽力分析这些值。 |
| `auto_generate_phrase_queries` | 默认False |
| `max_determinized_states` | 限制允许创建多少个自动机状态regexp查询。 这防止了太难的（例如指数级的）正则表达式。 默认为10000。 |
| `minimum_should_match` | 一个值，用于控制在生成的布尔查询中应该匹配多少个“应该”子句。 它可以是绝对值（2），百分比（30％）或两者的组合。 |
| `lenient` | 如果设置为true将导致基于格式的失败（例如向数字字段提供文本）被忽略。 |
| `locale` | 应用于字符串转换的区域设置。 默认为ROOT。 |
| `time_zone` | 要应用于与日期相关的任何范围查询的时区。 另请参阅JODA时区。 |

当生成多项查询时，可以控制如何使用rewrite参数重写它。

### 默认字段：

当未在查询字符串语法中显式指定要搜索的字段时，将使用index.query.default_field来导出要搜索的字段。 它默认为_all字段。

因此，如果_all字段被禁用，可能有必要更改它以设置不同的默认字段。

### 多个字段：

query_string查询也可以针对多个字段运行。 字段可以通过“fields”参数提供（如下例所示）。

对多个字段运行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)"
        }
    }
}
```

由于从单个搜索项生成了几个查询，因此可以使用dis_max查询或简单的bool查询自动完成组合。 例如（使用^ 5表示法将名称提升5）：

```
GET /_search
{
   "query": {
        "query_string" : {
            "fields" : ["content", "name^5"],
            "query" : "this AND that OR thus",
            "use_dis_max" : true
        }
    }
}
```

简单通配符也可以用于搜索文档的“内部”特定内部元素。 例如，如果我们有一个城市对象与多个字段（或内部对象与字段）在其中，我们可以自动搜索所有“城市”字段：

```
GET /_search
{
   "query": {
        "query_string" : {
            "fields" : ["city.*"],
            "query" : "this AND that OR thus",
            "use_dis_max" : true
        }
    }
}
```

另一个选项是在查询字符串本身中提供通配符字段搜索（正确转义*符号），例如：city。\ *：something。

对多个字段运行query_string查询时，允许以下附加参数：

| 参数 | 描述 |
| --- | --- |
| `use_dis_max` | 应该使用dis_max（设置为true）或bool查询（设置为false）组合查询。 默认为true。 |
| `tie_breaker` | 当使用dis_max时，断开最大断路器。 默认值为0。 |

fields参数还可以包括基于模式的字段名称，允许自动扩展到相关字段（包括动态引入的字段）。 例如：

```
GET /_search
{
"query": {
        "query_string" : {
            "fields" : ["content", "name.*^5"],
            "query" : "this AND that OR thus",
            "use_dis_max" : true
        }
    }
}
```

## 查询字符串语法

查询字符串“迷你语言”由查询字符串查询和查询API中的q查询字符串参数使用。

查询字符串被解析为一系列的术语和运算符。 术语可以是单个词 - quick 或brown 或一个短语，用双引号括起来 - “quick brown” - 以相同的顺序搜索短语中的所有单词。

操作员允许您自定义搜索 - 可用选项如下所述。

### 字段名称

如查询字符串查询中所述，搜索default_field是为了搜索搜索词，但可以在查询语法中指定其他字段

如在status字段内包含active

```
status:active
```

以下表示标题字段包含快速或棕色。 如果省略OR运算符，将使用默认运算符

```
title:(quick OR brown)
title:(quick brown)
```

以下表示作者字段包含确切的短语“john smith”

```
author:"John Smith"
```

表示包含任何字段book.title，book.content或book.date包含quick 或brown（注意我们如何需要用反斜杠转义*）

```
book.\*:(quick brown)
```

以下表示字段标题具有任何非空值

```
_exists_:title
```

### 通配符

通配符搜索可以使用单个术语运行？ 替换单个字符，*替换零个或多个字符：

```
qu?ck bro*
```

请注意，通配符查询会使用大量的内存并且执行得效率非常慢 - 只需考虑需要查询多少条件来匹配查询字符串“a * b * c *”

```
在字的开头允许通配符（例如“* ing”）特别耗性能，因为索引中的所有项都需要检查，以防它们匹配。 可以通过将allow_leading_wildcard设置为false来禁用主导通配符。
```

默认情况下不会分析通配字词 - 它们是小写的（lowercase_expanded_terms默认为true），但不进行进一步的分析，主要是因为无法准确分析缺少某些字母的单词。但是，通过将analyze_wildcard设置为true，将尝试在搜索术语列表以匹配术语之前分析通配字。

### 正则表达式

正则表达式模式可以通过以正斜线（“/”）包裹在查询字符串中来嵌入：

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

说明了正则表达式语法中受支持的正则表达式语法。

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

```
/.*n/
```

要谨慎使用。

### 模糊性

我们可以使用“fuzzy”运算符搜索与我们的搜索字词类似但不完全相似的字词：

```
quikc~ brwn~ foks~
```

这使用Damerau-Levenshtein距离找到所有最多只有两个变化的术语，其中一个变化是单个字符的插入，删除或替换，或两个相邻字符的变换。

默认编辑距离为2，但编辑距离为1应足以捕获所有人为拼写错误的80％。 它可以指定为：

```
quikc~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]
```

标签在alpha到omega之间但不包含alpha和omega

```
tag:{alpha TO omega}
```

数字1到无群大

```
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)
```

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

### 特殊字符

使用boost运算符^使一个术语比另一个更相关。 例如，如果我们想查找关于狐狸的所有文档，但我们对快速狐狸特别感兴趣：

```
quick^2 fox
```

默认提升值为1，但可以是任何正浮点数。 在0和1之间升高降低相关性。

提升也可以应用于短语或组：

```
"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（也写为&&，||和！）。

然而，这些操作符的效果可能比第一眼明显的复杂。

NOT优先于AND，优先于OR。 而+和 - 只影响运算符右边的项，AND和OR可以影响左边和右边的项。

```
使用AND，OR和NOT重写上述查询表明复杂性：
quick OR brown AND fox AND NOT news
这是不正确的，因为brown现在是必需的术语。
(quick OR brown) AND fox AND NOT news
这是不正确的，因为现在需要快速或棕色中的至少一个，并且对这些术语的搜索将与原始查询不同地打分。
((quick AND fox) OR (brown AND fox) OR fox) AND NOT news
此表单现在正确复制原始查询的逻辑，但相关性评分与原始查询具有很少相似性。
相反，使用匹配查询重写的同一查询将如下所示：

{
    "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。

保留字符为：+ - = && || &gt; &lt;！ （）{} [] ^“〜*？：\ /

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

```
请看这里：
空格也可以是保留字符。 例如，如果你有一个同义词列表将“wi fi”转换为“wifi”，query_string搜索“wi fi”将失败。 
查询字符串解析器会将您的查询解释为搜索“wi OR fi”，而存储在索引中的条件实际上是“wifi”。 
转义空格将保护它不被查询字符串解析器，如：“wi \ fi”。
```

### 空查询

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