Elasticsearch 映射(Mapping)

╰+攻爆jí腚メ 2021-12-01 11:18 552阅读 0赞

什么是 Mapping

Mapping(映射): 是用来定义文档和它所包含的字段是如何被存储和索引的。

mapping 有点像 MySQL 中的数据表结构定义。

在 Elasticsearch 中,mapping 可以定义(明确规定)以下内容:

  • 字符串字段是否应当被看作 Full Text(全文本)或精确的字符串值
  • 字段的数据类型(数值、日期或者地理位置)
  • 文档中所有字段的值是否应当索引到 _all 字段
  • date 数据类型的字段值的存储格式
  • 对动态添加的字段,自定义映射规则

Mapping Type

前面说过,type(类型、类别)是一种虚拟的逻辑分类,用于将索引库(index)中的文档(document)划分为不同的逻辑分组。

Type 类似于 MySQL 中的数据表。

Elasticsearch 6.x 版本只允许每个 Index 包含一个 Type,7.x 版本已彻底移除 Type。

说明: 我用的是 Elasticsearch 5.2,为了便于向 6.x 甚至 7.x 版本过渡,推荐每个 Index 只包含一个 Type(而不要采用 1 对多)。

Type 包含以下内容:

  • Meta-fields(元字段): 主要包含文档的 _index、_type、_id、_score 和 _source 字段。
  • Properties or fields(属性或字段): 这里的 Properties 指的是源文档的属性或字段。文档可能包含标题、名称、年龄、创建时间等。

数据类型

每一个字段都有对应的数据类型,数据类型包含以下几种:

  • 基本类型,如 text, keyword, date, long, double, boolean, ip
  • 复合类型,如 object, nested
  • 特殊类型,如 geo_point, geo_shape, completion.

在 Elasticsearch 中,同一个字段可以对应多种数据类型。

比如,同一个字符串字段经常被用于指定两种数据类型:

  • text 类型,会被分词和索引,用于全文搜索。
  • keyword 类型,用于排序或者聚合。

你可以用 standard analyzer, english analyzer, french analyzer 或者自定义的分析器(分词器)来分析和索引字符串字段。

大多数数据类型的字段都支持多字段数据类型,你可以通过字段的 fields 属性来实现。

动态映射

在创建索引库时,我们可以同时指定 Mapping,来明确指定文档中的字段的数据类型等。

但是,就算我们没有手动指定 Mapping,直接创建文档时,Elasticsearch 也会自动对文档中的字段进行映射。并且,后来新出现的字段也会被自动映射。这就是动态映射

例如,我们直接在 Elasticsearch 中创建(索引)一个文档。

  1. PUT /test/counters/1
  2. { "count": 5 }

这里,test 索引库和 counters 类型都是自动生成的,并且也自动生成了对应的 Mapping。

我们来查看一下它的 Mapping。

  1. GET /test/_mapping/counters

返回结果:

  1. {
  2. "test": {
  3. "mappings": {
  4. "counters": {
  5. "properties": {
  6. "count": {
  7. "type": "long"
  8. }
  9. }
  10. }
  11. }
  12. }
  13. }

然后,我们再来创建一个文档,新增了 created_date 字段。

  1. PUT /test/counters/2
  2. { "count": 6, "created_date":"2019-06-09" }

再来查看它的 Mapping,结果如下:

  1. {
  2. "test": {
  3. "mappings": {
  4. "counters": {
  5. "properties": {
  6. "count": {
  7. "type": "long"
  8. },
  9. "created_date": {
  10. "type": "date"
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

显式映射

显式映射是指你想要手动明确地指定映射。

当然,我们自己要比 Elasticsearch 更清楚文档中的字段应当以何种数据类型进行存储更为合适。因此,显式映射尤为重要。

创建索引库时定义映射

  1. PUT /twitter
  2. {
  3. "mappings": {
  4. "tweet": {
  5. "properties": {
  6. "message": {
  7. "type": "text"
  8. }
  9. }
  10. }
  11. }
  12. }

新增映射字段

  1. PUT /twitter/_mapping/tweet
  2. {
  3. "properties": {
  4. "user_name": {
  5. "type": "text"
  6. }
  7. }
  8. }

更新已经存在的字段映射

一般来说,已经存在的字段映射是不允许再更改的,因为如果索引库中已经存在该文档,更新映射可能导致已存在的索引失效。

但是,也有一些例外:

  • 可以给 object 类型的字段添加新的属性。
  • 可以给字段添加多字段类型。
  • 可以更新字段的 ignore_above。

示例:

  1. PUT /my_index
  2. {
  3. "mappings": {
  4. "user": {
  5. "properties": {
  6. "name": {
  7. "properties": {
  8. "first": {
  9. "type": "text"
  10. }
  11. }
  12. },
  13. "user_id": {
  14. "type": "keyword"
  15. }
  16. }
  17. }
  18. }
  19. }
  20. PUT /my_index/_mapping/user
  21. {
  22. "properties": {
  23. "name": {
  24. "properties": {
  25. "last": {
  26. "type": "text"
  27. }
  28. }
  29. },
  30. "user_id": {
  31. "type": "keyword",
  32. "ignore_above": 100
  33. }
  34. }
  35. }

除了上述例外,最好的做法是用正确的 mapping 创建新的索引库,然后将你的文档记录重新索引。

查看映射

查看 mapping 的基本命令格式为:

  1. GET /<索引库>/_mapping/<类型>

例如:

  1. GET /alibaba/_mapping/user

返回结果:

  1. {
  2. "alibaba": {
  3. "mappings": {
  4. "user": {
  5. "properties": {
  6. "created_at": {
  7. "type": "text",
  8. "fields": {
  9. "keyword": {
  10. "type": "keyword",
  11. "ignore_above": 256
  12. }
  13. }
  14. },
  15. "email": {
  16. "type": "text",
  17. "fields": {
  18. "keyword": {
  19. "type": "keyword",
  20. "ignore_above": 256
  21. }
  22. }
  23. },
  24. "first_name": {
  25. "type": "text",
  26. "fields": {
  27. "keyword": {
  28. "type": "keyword",
  29. "ignore_above": 256
  30. }
  31. }
  32. },
  33. "full_name": {
  34. "type": "text",
  35. "fields": {
  36. "keyword": {
  37. "type": "keyword",
  38. "ignore_above": 256
  39. }
  40. }
  41. },
  42. "info": {
  43. "properties": {
  44. "address": {
  45. "type": "text",
  46. "fields": {
  47. "keyword": {
  48. "type": "keyword",
  49. "ignore_above": 256
  50. }
  51. }
  52. },
  53. "age": {
  54. "type": "long"
  55. },
  56. "interests": {
  57. "type": "text",
  58. "fields": {
  59. "keyword": {
  60. "type": "keyword",
  61. "ignore_above": 256
  62. }
  63. }
  64. }
  65. }
  66. },
  67. "last_name": {
  68. "type": "text",
  69. "fields": {
  70. "keyword": {
  71. "type": "keyword",
  72. "ignore_above": 256
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }

说明: 该映射是我们在前面的小节中,直接创建(索引)文档时,由 Elasticsearch 根据 JSON 文档自动生成的。

参考文献

[1] https://www.elastic.co/guide/en/elasticsearch/reference/5.2/index.html

发表评论

表情:
评论列表 (有 0 条评论,552人围观)

还没有评论,来说两句吧...

相关阅读