映射及分析

当在索引中处理数据时,我们注意到一些奇怪的事。有些东西似乎被破坏了:

在索引中有12个tweets,只有一个包含日期2014-09-15,但是我们看看下面查询中的total hits。

  1. GET /_search?q=2014 # 12 个结果
  2. GET /_search?q=2014-09-15 # 还是 12 个结果 !
  3. GET /_search?q=date:2014-09-15 # 1 一个结果
  4. GET /_search?q=date:2014 # 0 个结果 !

为什么全日期的查询返回所有的tweets,而针对date字段进行年度查询却什么都不返回?
为什么我们的结果因查询_all字段(译者注:默认所有字段中进行查询)或date字段而变得不同?

想必是因为我们的数据在_all字段的索引方式和在date字段的索引方式不同而导致。

让我们看看Elasticsearch在对gb索引中的tweet类型进行mapping(也称之为模式定义[注:此词有待重新定义(schema definition)])后是如何解读我们的文档结构:

  1. GET /gb/_mapping/tweet

返回:

  1. {
  2. "gb": {
  3. "mappings": {
  4. "tweet": {
  5. "properties": {
  6. "date": {
  7. "type": "date",
  8. "format": "dateOptionalTime"
  9. },
  10. "name": {
  11. "type": "string"
  12. },
  13. "tweet": {
  14. "type": "string"
  15. },
  16. "user_id": {
  17. "type": "long"
  18. }
  19. }
  20. }
  21. }
  22. }
  23. }

Elasticsearch为对字段类型进行猜测,动态生成了字段和类型的映射关系。返回的信息显示了date字段被识别为date类型。_all因为是默认字段所以没有在此显示,不过我们知道它是string类型。

date类型的字段和string类型的字段的索引方式是不同的,因此导致查询结果的不同,这并不会让我们觉得惊讶。

你会期望每一种核心数据类型(strings, numbers, booleans及dates)以不同的方式进行索引,而这点也是现实:在Elasticsearch中他们是被区别对待的。

但是更大的区别在于确切值(exact values)(比如string类型)及全文文本(full text)之间。

这两者的区别才真的很重要 - 这是区分搜索引擎和其他数据库的根本差异。