• 7.elasticsearch字段类型列表


    【README】

    1.本文总结自  Field datatypes | Elasticsearch Guide [7.2] | Elastic

    2.本文罗列了 elasticsearch常用的字段类型;

    3.es字段类型总结(https://www.elastic.co/guide/en/elasticsearch/reference/7.2/mapping-types.html):

    • 1)核心数据类型:
      • string字符串:
        • text:文本类型(分词);
        • keyword:关键字类型(不分词);
      • numeric-数值类型:
        • long, integer, short, byte, double, float, half_float, scaled_float  
      • date-日期类型(存储自unix纪元以来的毫秒数);
      • date_nanos:日期纳秒类型(存储自unix纪元以来的纳秒数);
      • boolean-布尔类型;
      • binary-二进制类型;
      • range-范围类型:    
        • integer_range, float_range, long_range, double_range, date_range
    • 2)复杂数据类型
      • object:对象类型;存储单个json对象;
      • nested:嵌套类型;存储json对象数组;    
    • 3)数组类型(字段数组类型)
      • 数组不需要专用的数据类型。一个字段默认可以包含0个或多个值。然而,数组中的所有值必须是同一种类型;
    • 4)多字段类型:
      • 根据不同目的以不同方式索引同一字段是有帮助的;
      • 举例,字符串字段可以被映射为 text字段以便全文搜索,也可以映射为keword以便于排序或聚合。
    • 5)其他数据类型
      • 如地理位置信息数据类型,ip数据类型等(没有罗列完全);

    【1】核心数据类型

    【1.1】string字符串(分词

    1)text类型:文本类型(分词)

    • 用于定义索引全文值的字段,如电子邮件或产品描述。
    • 这些字段会被分析,即在索引前,这些字段会通过一个分析器把字符串转换为单个单词的列表。该分析过程允许es在每个全文字段中搜索单个词汇。Text字段(文本字段)不用于排序与聚合
    • 如果你需要索引结构化内容,如邮件地址,域名,邮编等,也许你应该使用keyword字段类型;
    • 补充; text字段参数列表参见; https://www.elastic.co/guide/en/elasticsearch/reference/7.2/text.html

    2)keyword:关键字类型(不分词)

    • 用于定义索引结构化内容的字段,如邮件地址,域名,邮编等。
    • 它们通常用于过滤(查找我所有被发表过的博客帖子),排序,聚合。Keyword字段只能通过他们的精确值被搜索到。
    • 补充;keyword字段参数列表参见;https://www.elastic.co/guide/en/elasticsearch/reference/7.2/keyword.html

    【1.2】Numeric-数值类型

    数值类型的子类型列表:

    • long, integer, short, byte, double, float, half_float, scaled_float 
    • scaled_float 是缩放参数,即 99.99 可以放大100倍进行存储,好处有二:
      • 1,可以节省磁盘空间;
      • 2, 可以提高检索效率;

    1. // 建立索引映射,带有 数值类型
    2. PUT my_index
    3. {
    4. "mappings": {
    5. "properties": {
    6. "number_of_bytes": {
    7. "type": "integer"
    8. },
    9. "time_in_seconds": {
    10. "type": "float"
    11. },
    12. "price": {
    13. "type": "scaled_float",
    14. "scaling_factor": 100
    15. }
    16. }
    17. }
    18. }

     【1.3】date日期类型

    1)Json并没有日期数据类型,因此es中的date字段表示为以下几种形式之一

    • ① 字符串类型:包含格式化日期,如 “2015-01-01”或 “2015/01/01 12:10:13”;
    • ② 长整型数字:表示自unix纪元以来的毫秒数;
    • ③ 整型数字:表示自unix纪元以来的秒数;

    补充:unix纪元是 1970-01-01 00:00:00
    2)在es内部,日期被转为世界标准时间UTC(若指定时区)并存储为长整型表示自纪元以来的毫秒数;
    3)对日期的查询:

    • 在es内部,被转为对长整型数字的范围查询,聚合结果和存储的字段根据关联的日期格式被反转为字符串;

    4)日期通常表示为字符串,即便在json文档中以long类型提供;
    5)日期格式能够自定义,但若没有指定格式,则默认为如下格式:

    • "strict_date_optional_time||epoch_millis"

    这意味着该字段可以接收可选的时间戳日期,这些时间戳符合 strict_date_optional_time 或 milliseconds-since-the-epoch 支持的格式。

    6)多个日期格式:

    • 多个日期格式通过||分割符通过分割来指定。每个格式将被循环尝试直到发现匹配格式。第一个格式将被用于把自纪元以来的毫秒数值反转为字符串;
    1. PUT my_index
    2. {
    3. "mappings": {
    4. "properties": {
    5. "date": {
    6. "type": "date",
    7. "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
    8. }
    9. }
    10. }
    11. }

    【1.4】date_nanos (日期带纳秒类型  )

    1)该数据类型是对date类型的补充。 然而,两者有着很大不同。

    • date类型使用毫秒分辨率存储日期字段值;
    • 而 date_nanos 使用纳秒,这限制了 date_nanos的日期表示范围是 1970到2262年,因为日期字段值被存储为长整型表示自纪元以来的纳秒。

    2)date_nanos的其他属性同 date类型。如

    1. PUT my_index?include_type_name=true
    2. {
    3. "mappings": {
    4. "_doc": {
    5. "properties": {
    6. "date": {
    7. "type": "date_nanos"
    8. }
    9. }
    10. }
    11. }
    12. }

    【1.5】boolean-布尔类型

    1)boolean 接收json的true 和 false值,也接收能够解释为 true或false 的字符串。

    • false值: false,”false”, “”
    • true值: true , “true”

    2)例子:

    1. PUT my_index
    2. {
    3. "mappings": {
    4. "properties": {
    5. "is_published": {
    6. "type": "boolean"
    7. }
    8. }
    9. }
    10. }

    【1.6】binary-二进制类型

    1)二进制类型接收二进制值作为base64编码的字符串。该类型字段默认不存储且不能被搜索。

    1. // 创建索引
    2. PUT my_index
    3. {
    4. "mappings": {
    5. "properties": {
    6. "name": {
    7. "type": "text"
    8. },
    9. "blob": {
    10. "type": "binary"
    11. }
    12. }
    13. }
    14. }
    15. // 新增文档
    16. PUT my_index/_doc/1
    17. {
    18. "name": "Some binary blob",
    19. "blob": "U29tZSBiaW5hcnkgYmxvYg=="
    20. }

    【1.7】范围类型 (不常用)

    1)范围子类型有:

    • integer_range, float_range, long_range, double_range, date_range
    1. // 创建索引
    2. PUT range_index
    3. {
    4. "settings": {
    5. "number_of_shards": 2
    6. },
    7. "mappings": {
    8. "properties": {
    9. "expected_attendees": {
    10. "type": "integer_range"
    11. },
    12. "time_frame": {
    13. "type": "date_range",
    14. "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
    15. }
    16. }
    17. }
    18. }
    19. // 新增文档
    20. PUT range_index/_doc/1?refresh
    21. {
    22. "expected_attendees" : {
    23. "gte" : 10,
    24. "lte" : 20
    25. },
    26. "time_frame" : {
    27. "gte" : "2015-10-31 12:00:00",
    28. "lte" : "2015-11-01"
    29. }
    30. }

    【2】复杂数据类型

    【2.1】object-对象类型

    1)对象类型:针对单个json文档 ;

    • Json对象类型本质上是分层的。文档可能包含内部对象,而内部对象还可以包含内部对象(理论上无限嵌套,但嵌套层数越多,解析成本越高,性能越低)。

    2)es文档类型

    1. PUT my_index/_doc/1
    2. {
    3. "region": "US",
    4. "manager": {
    5. "age": 30,
    6. "name": {
    7. "first": "John",
    8. "last": "Smith"
    9. }
    10. }
    11. }
    12. // 内部地,这个文档被索引为简单的,扁平的kv键值对列表,如下:
    13. {
    14. "region": "US",
    15. "manager.age": 30,
    16. "manager.name.first": "John",
    17. "manager.name.last": "Smith"
    18. }
    19. // es映射定义如下:
    20. PUT my_index
    21. {
    22. "mappings": {
    23. "properties": {
    24. "region": {
    25. "type": "keyword"
    26. },
    27. "manager": {
    28. "properties": {
    29. "age": { "type": "integer" },
    30. "name": {
    31. "properties": {
    32. "first": { "type": "text" },
    33. "last": { "type": "text" }
    34. }
    35. }
    36. }
    37. }
    38. }
    39. }
    40. }

    【2.2】nested嵌套类型(用于存储json对象数组)

    1)嵌套类型:针对 json文档数组 ;
    2)这种 nested 嵌套类型是object 类型的特别版本,它允许对象数组被索引,通过这种方式使得数组元素可以被独立搜索;
    3)数组对象如何被扁平化

    • object类型字段的数组无法如你期望的方式工作。Lucene没有内部object的概念,因此es把对象层级扁平化为简单的字段名和值列表

    【2.2.1】es对对象层级的扁平化处理(es用对象类型存储对象数组带来的问题

    1. PUT my_index/_doc/1
    2. {
    3. "group" : "fans",
    4. "user" : [
    5. {
    6. "first" : "John",
    7. "last" : "Smith"
    8. },
    9. {
    10. "first" : "Alice",
    11. "last" : "White"
    12. }
    13. ]
    14. }
    15. // user 字段被es默认设置为object类型

    在es内部,该json对象会被转换为如下文档。

    1. {
    2. "group" : "fans",
    3. "user.first" : [ "alice", "john" ],
    4. "user.last" : [ "smith", "white" ]
    5. }

    使用es对象类型存储对象数组带来的问题

    • User.first 和 user.last 字段展平为多值字段,而 alice和white的关联丢失了。这会导致文档错误匹配上  user.first = alice 且 user.last = smith
    • 即 对象{first:John, last:Smith} 与 对象 {first:Alice, last: White} 之间的对象边界没有了;这显然不符合我们的预期;

    【2.2.2】es存储json数组的解决方案:使用 nested嵌套类型存储对象数组

    1)如果你需要索引对象数组且保持数组中每个对象的独立性,你应该使用 nested嵌套数据类型,而不是object对象类型

    2)在es内部,嵌套类型把数组中的每个对象索引为单个隐藏文档,这意味着每一个嵌套对象能够独立于其他嵌套对象被搜索。

    3)嵌套搜索dsl如下:

    1. // 创建索引 (带有嵌套数据类型-nested)
    2. PUT my_index
    3. {
    4. "mappings": {
    5. "properties": {
    6. "user": {
    7. "type": "nested"
    8. }
    9. }
    10. }
    11. }
    12. // 新增文档 (以数组形式新增文档到嵌套类型)
    13. PUT my_index/_doc/1
    14. {
    15. "group" : "fans",
    16. "user" : [
    17. {
    18. "first" : "John",
    19. "last" : "Smith"
    20. },
    21. {
    22. "first" : "Alice",
    23. "last" : "White"
    24. }
    25. ]
    26. }
    27. // 搜索文档 (嵌套查询dsl)
    28. GET my_index/_search
    29. {
    30. "query": {
    31. "nested": {
    32. "path": "user",
    33. "query": {
    34. "bool": {
    35. "must": [
    36. { "match": { "user.first": "Alice" }},
    37. { "match": { "user.last": "Smith" }}
    38. ]
    39. }
    40. }
    41. }
    42. }
    43. }

    4)nested-嵌套文档能够进行如下操作:

    • 嵌套搜索(nested query);
    • 使用嵌套分词和逆嵌套聚合(逆嵌套-reverse_nested);
    • 嵌套排序(nested sorting);
    • 根据嵌套内部命中实现检索和高亮(nested inner hits);

    5)对nested嵌套映射和对象的限制设置
    如以上描述所说,每一个嵌套文档会被索引为独立文档

    • 如果我们索引包含100个user对象的的单个文档,实际上产生了101个文档。因为user是嵌套字段,100个user每个user各自一个文档,父文档也要单独创建一个文档。

    因为涉及到nested嵌套映射的成本,es需要做一些设置以防出现性能问题

    • ① index.mapping.nested_fields.limit
      • 嵌套类型应该只被在特殊场景下使用,当数组对象需要被独立搜索时。为防止设置出不佳的映射,此设置(index.mapping.nested_fields.limit)限制了每个索引的嵌套字段数量。
      • es默认每个索引最多可以包含50个嵌套字段
    • ② index.mapping.nested_objects.limit:
      • 此设置(index.mapping.nested_objects.limit)限制了单个文档包含的嵌套对象的数量,以防止一个文档包含过多嵌套对象时报内存溢出错误。
      • Es默认情况下,一个文档包含的嵌套文档数量最多是10000个

    【3】数组类型(字段数组类型)

    在es中, 数组不需要专用的数据类型

    • 一个字段默认可以包含0个或多个值。然而,数组中的所有值必须是同一种类型

    【4】多字段类型

    1)根据不同目的以不同方式索引同一字段是有帮助的;

    • 举例,字符串字段可以被映射为 text字段以便全文搜索,也可以同时映射为keword以便于排序或聚合。

    2)此外,你还可以用标准分词器,英文分词器或法语分词器来索引text字段;
    3)通过 fields 参数来指定同一个字段的多种数据类型。

    • 参见: https://www.elastic.co/guide/en/elasticsearch/reference/7.2/multi-fields.html
      1. // 字符串字段可以被映射为 text字段以便全文搜索
      2. // 也可以同时映射为keword以便于排序或聚合
      3. PUT my_index
      4. {
      5. "mappings": {
      6. "properties": {
      7. "city": {
      8. "type": "text",
      9. "fields": {
      10. "raw": {
      11. "type": "keyword"
      12. }
      13. }
      14. }
      15. }
      16. }
      17. }

    【5】其他数据类型

    如 地理位置信息数据类型,ip数据类型等。
    详情参见:  https://www.elastic.co/guide/en/elasticsearch/reference/7.2/mapping-types.html

  • 相关阅读:
    windows下flume配置不成功
    Ubuntu 22.04 安装 Terraform
    〖全域运营实战白宝书 - 高转化文案速成篇②〗- 快速找到产品卖点的N个小技巧
    十、JVM常用启动参数
    初识二叉搜索树
    【工具配置篇】VSCode 常用使用总结
    vue模板语法上集
    StringComparer 几个用法举例
    AlexNet重点介绍和源码测试
    Cloud-Sleuth分布式链路追踪(服务跟踪)
  • 原文地址:https://blog.csdn.net/PacosonSWJTU/article/details/127200021