# 查询语句

搜索的API分为两种：其一是通过参数来传递查询的“精简版”*查询语句（query string）*，还有一种是通过JSON来传达丰富的查询的完整版*请求体（request body）*，这种搜索语言被称为查询DSL。

查询语句在行命令中运行点对点查询的时候非常实用。比如我想要查询所有`tweet`类型中，所有`tweet`字段为`"elasticsearch"`的文档：

```javascript
GET /_all/tweet/_search?q=tweet:elasticsearch
```

下一个查询是想要寻找`name`字段为`"john"`且`tweet`字段为`"mary"`的文档，实际的查询就是：

```
+name:john +tweet:mary
```

但是经过*百分号编码（percent encoding）*&#x5904;理后，会让它看起来稍显神秘:

```javascript
GET /_search?q=%2Bname%3Ajohn+%2Btweet%3Amary
```

前缀`"+"`表示**必须要**满足我们的查询匹配条件，而前缀`"-"`则表示**绝对不能**匹配条件。没有`+`或者`-`的表示可选条件。匹配的越多，文档的相关性就越大。

### 字段`_all`

下面这条简单的搜索将会返回所有包含`"mary"`字符的文档：

```javascript
GET /_search?q=mary
```

在之前的例子中，我们搜索`tweet`或者`name`中的文字。然而，搜索的结果显示`"mary"`在三个不同的字段中：

* 用户的名字为"Mary"
* 6个"Mary"发送的推文
* 1个"@mary"

那么Elasticsearch是如何找到三个不同字段中的内容呢？

当我们在索引一个文档的时候，Elasticsearch会将所有字段的数值都汇总到一个大的字符串中，并将它索引成一个特殊的字段`_all`：

```javascript
{
    "tweet":    "However did I manage before Elasticsearch?",
    "date":     "2014-09-14",
    "name":     "Mary Jones",
    "user_id":  1
}
```

就好像我们已经添加了一个叫做`_all`的字段：

```javascript
"However did I manage before Elasticsearch? 2014-09-14 Mary Jones 1"
```

除非指定了字段名，不然查询语句就会搜索字段`_all`。

TIP: 在你刚开始创建程序的时候你可能会经常使用`_all`这个字段。但是慢慢的，你可能就会在请求中指定字段。当字段`_all`已经没有使用价值的时候，那就可以将它关掉。之后的《字段all》一节中将会有介绍

## 更加复杂的查询

再实现一个查询：

* 字段`name`包含`"mary"`或`"john"`
* `date`大于`2014-09-10`
* `_all`字段中包含`"aggregations"`或`"geo"`

```javascript
+name:(mary john) +date:>2014-09-10 +(aggregations geo)
```

最终处理完的语句可读性可能很差：

```
?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)
```

正如你所看到的，这个*简明*查询语句是出奇的强大。在[查询语句语法](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current//query-dsl-query-string-query.html#query-string-syntax)中，有关于它详细的介绍。借助它我们就可以在开发的时候提高很多效率。

不过，你也会发现简洁带来的易读性差和难以调试，以及它的脆弱：当其中出现`-`, `:`, `/` 或者 `"`时，它就会返回错误提示。

最后要提一句，任何用户都可以通过查询语句来访问臃肿的查询，或许会得到一些私人的信息，或许会通过大量的运算将你的集群压垮！

> ### TIP

出于以上原因，我们不建议你将查询语句直接暴露给用户，除非是你信任的可以访问数据与集群的权限用户。

与此同时，在生产环境中，我们经常会使用到查询语句。在了解更多关于搜索的知识前，我们先来看一下它是怎样运作的。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hezhiqiang.gitbook.io/elasticsearch/search/query_string.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
