在看《Elasticsearch: 权威指南》时,看到这么个问题,解决了我的疑问:
当摆弄索引里面的数据时,我们发现一些奇怪的事情。一些事情看起来被打乱了:在我们的索引中有12条推文,其中只有一条包含日期 2014-09-15 ,但是看一看下面查询命中的 总数 (total):
GET /_search?q=2014 # 12 results GET /_search?q=2014-09-15 # 12 results ! GET /_search?q=date:2014-09-15 # 1 result GET /_search?q=date:2014 # 0 results !
为什么在 _all 字段查询日期返回所有推文,而在 date 字段只查询年份却没有返回结果?为什么我们在 _all 字段和 date 字段的查询结果有差别?
推测起来,这是因为数据在 _all 字段与 date 字段的索引方式不同。所以,通过请求 gb 索引中 tweet类型的_映射_(或模式定义),让我们看一看 Elasticsearch 是如何解释我们文档结构的:
GET /gb/_mapping/tweet
这将得到如下结果:
{
"gb": {
"mappings": {
"tweet": {
"properties": {
"date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"name": {
"type": "string"
},
"tweet": {
"type": "string"
},
"user_id": {
"type": "long"
}
}
}
}
}
}
基于对字段类型的猜测, Elasticsearch 动态为我们产生了一个映射。这个响应告诉我们 date 字段被认为是 date 类型的。由于 _all 是默认字段,所以没有提及它。但是我们知道 _all 字段是 string 类型的。
所以 date 字段和 string 字段 索引方式不同,因此搜索结果也不一样。这完全不令人吃惊。你可能会认为 核心数据类型 strings、numbers、Booleans 和 dates 的索引方式有稍许不同。没错,他们确实稍有不同。
但是,到目前为止,最大的差异在于 代表 精确值 (它包括 string 字段)的字段和代表 全文 的字段。这个区别非常重要——它将搜索引擎和所有其他数据库区别开来。
date域包含一个精确值:单独的词条 `2014-09-15`。_all域是一个全文域,所以分词进程将日期转化为三个词条: `2014`, `09`, 和 `15`。
当我们在 _all 域查询 2014`,它匹配所有的12条推文,因为它们都含有 `2014 :
GET /_search?q=2014 # 12 results
当我们在 _all 域查询 2014-09-15`,它首先分析查询字符串,产生匹配 `2014`, `09`, 或 `15 中 任意 词条的查询。这也会匹配所有12条推文,因为它们都含有 2014 :
GET /_search?q=2014-09-15 # 12 results !
当我们在 date 域查询 `2014-09-15`,它寻找 精确 日期,只找到一个推文:
GET /_search?q=date:2014-09-15 # 1 result
当我们在 date 域查询 `2014`,它找不到任何文档,因为没有文档含有这个精确日志:
GET /_search?q=date:2014 # 0 results !
https://www.elastic.co/guide/cn/elasticsearch/guide/current/mapping-analysis.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/analysis-intro.html
探讨Elasticsearch中_all字段与date字段的索引差异,解析查询结果不同的原因,及如何正确使用映射和分析。
3120

被折叠的 条评论
为什么被折叠?



