# Executing Searches（执行查询）

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/5.4/_executing_searches.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/_executing_searches.html)

译文链接 : [http://www.apache.wiki/pages/viewpage.action?pageId=4260761](http://www.apache.wiki/pages/viewpage.action?pageId=4260761)

贡献者 : [那伊抹微笑](/display/~wangyangting)，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

现在我们已经了解了一下基本的搜索参数，让我们深入探讨更多的 **DSL**。我们首先看一下返回的文档的字段。默认情况下，完成的 **JSON** 文档被作为所有搜索的一部分返回。这被称为源（在搜索 **hits** 中的 **_source** 字段）。如果我们不希望整个源文档返回，我们可以只请求源中的一些字段返回。

下面的例子演示了如何返回两个字段，**account_number** 和 **balance**（在 **_source** 之内），从 **search** 开始，如下所示 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}'
```

注意，上面的例子减少了 **_source** 字段，它将仍然只返回一个名为 **_source** 的字段，但是不在它里面，仅包括 **account_number** 和 **balance** 字段。

如果您拥有 **SQL** 基础，上面的地方与 **SQL SELECT** **FROM** 字段列表的概念相似。

现在让我们继续查询部分。此前，我们了解了 **match_all** 是如何匹配所有文档的。我们现在介绍一个名为 [`match` query](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/query-dsl-match-query.html "Match Query") 的新的查询，可以认为它是搜索查询的一个基础的字段（例如，针对一个指定的字段或一组字段来搜索）。

这个例子返回了账户编号为 **20** 的文档 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match": { "account_number": 20 } }
}'
```

这个例子返回了所有在 **address** 中包含 **term** 为 “**mill**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match": { "address": "mill" } }
}'
```

这个例子返回了所有在 **address** 中包含了 **term** 为 “**mill**” 或 “**lane**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match": { "address": "mill lane" } }
}'
```

这个例子是 **match**（**match_phrase**）的另一种方式，它返回了在 **address** 中所有包含 **phrase** 为 “**mill** **lane**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": { "match_phrase": { "address": "mill lane" } }
}'
```

现在我们介绍 [`bool`(ean) query](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/query-dsl-bool-query.html "Bool Query")。该 **bool** 查询可以让我们使用 **boolean** 逻辑构建较小的查询到更大的查询中去。

这个例子构建两个 **match** 查询，并且回了所有在 **address** 中包含了 “**mill**” 和 “**lane**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}'
```

在上面的例子中，**bool** **must** 语句指定了所有查询必须为 **true** 时将匹配到文档。

相反，这个例子构建两个 **match** 查询，并且回了所有在 **address** 中包含了 “**mill**” 或 “**lane**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}'
```

在上面的例子中，**bool** **should** 语句指定了一个查询列表，两者中的一个为 **true** 时将匹配到文档。

这个例子构建两个 **match** 查询，并且回了所有在 **address** 中既不包含 “**mill**” 也不包含 “**lane**” 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}'
```

在上面的例子中，**bool** **must_not** 语句指定了一个查询列表，都不为 **true** 将匹配到文档。

我们可以在 **bool** 查询中同时联合 **must**，**should**，和 **must_not** 语句。

此外，我们可以在任何一个 **bool** 语句内部构建 **bool** 查询，从而模拟出任何复杂的多级别的 **boolean** 逻辑。

这个例子返回了 **age** 为 **40** 但是 **state** 不为 **ID** 的账户 : 

```
curl -XGET 'localhost:9200/bank/_search?pretty' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}'
```