问题：GET查询，加.keyword与不加.keyword的区别是什么，为什么没有结果
```
GET production-index-info/index_info/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 0,
      "must": [
        {
          "term": {
            "is_resolved.keyword": "解决"
          }
        }
      ],
      "should": []
    }
  }
}
```
使用这种方式查询，就可以得到数据。数据如下格式
```
{
  "took": 51,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2914867,
    "max_score": 0.26003557,
    "hits": [
      {
        "_index": "production-index-info",
        "_type": "index_info",
        "_id": "5a5d4fcdc42fbc2bcefae14a",
        "_score": 0.26003557,
        "_source": {
          "created_time": "2020-01-21T22:44:50+08:00",
          "tickets": [],
          "is_resolved": "解决",
          "note": "",
        }
      },
      {
        "_index": "production-index-info",
        "_type": "index_info",
        "_id": "5a64a762cd1cb23dbb294bfa",
        "_score": 0.26003557,
        "_source": {
          "created_time": "2018-01-21T22:44:50+08:00",
          "tickets": [],
          "is_resolved": "解决",
          "note": "",
        }
      },
      {
        "_index": "production-index-info",
        "_type": "index_info",
        "_id": "5a5d88136817b27825831ac2",
        "_score": 0.26003557,
        "_source": {
          "created_time": "2018-01-16T13:05:23+08:00",
          "tickets": [],
          "is_resolved": "解决",
          "note": "11111",
        }
      },
      {
        "_index": "production-index-info",
        "_type": "index_info",
        "_id": "5a5dbc30c42fbc2ef1307ba9",
        "_score": 0.26003557,
        "_source": {
          "created_time": "2018-01-16T16:47:44+08:00",
          "tickets": [],
          "is_resolved": "未解决",
          "note": "222",
        }
      },
      ......
    ]
  }
}
```
但是如果使用这种方式，删除了`.keywprd`，
```
GET production-index-info/index_info/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 0,
      "must": [
        {
          "term": {
            "is_resolved": "解决"
          }
        }
      ],
      "should": []
    }
  }
}
```
那么结果就是这样的
```
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}
```
我知道这个`.keyword`和分词有关，但是对于这个例子，没有搞懂为什么，加了`.keyword`才可以查询出来结果，不加就不行了。另外，is_resolved的值，只有解决和未解决两个。

回答：1.ES5.0及以后的版本取消了`string`类型，将原先的`string`类型拆分为`text`和`keyword`两种类型。它们的区别在于`text`会对字段进行分词处理而`keyword`则不会。
2.当你没有以IndexTemplate等形式为你的索引字段预先指定mapping的话，ES就会使用Dynamic Mapping，通过推断你传入的文档中字段的值对字段进行动态映射。例如传入的文档中字段price的值为12，那么price将被映射为`long`类型；字段addr的值为"192.168.0.1"，那么addr将被映射为`ip`类型。然而对于不满足ip和date格式的普通字符串来说，情况有些不同：ES会将它们映射为text类型，但为了保留对这些字段做精确查询以及聚合的能力，又同时对它们做了keyword类型的映射，作为该字段的fields属性写到_mapping中。例如，当ES遇到一个新的字段"foobar": "some string"时，会对它做如下的Dynamic Mapping：
```
{
    "foobar": {
        "type" "text",
        "fields": {
            "keyword": {
                "type": "keyword",
                "ignore_above": 256
            }
        }
    }
}
```
在之后的查询中使用foobar是将foobar作为text类型查询，而使用foobar.keyword则是将foobar作为keyword类型查询。前者会对查询内容做分词处理之后再匹配，而后者则是直接对查询结果做精确匹配。
3.ES的term query做的是精确匹配而不是分词查询，因此对text类型的字段做term查询将是查不到结果的（除非字段本身经过分词器处理后不变，未被转换或分词）。此时，必须使用foobar.keyword来对foobar字段以keyword类型进行精确匹配。

标签: elasticsearch, elastic-search, elk