elasticsearch 数据类型详解

这篇具有很好参考价值的文章主要介绍了elasticsearch 数据类型详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据类型

此文章已收录至项目 Developer-Knowledge-Base

官方文档:这里这里

  • 常见类型
    • binary:接受二进制值作为 Base64 编码的字符串。默认情况下,该字段不存储,也不可搜索,不能包含换行符 \n
    • boolean:布尔类型,可以接受 truefalse ,可以使用字符串和直接到布尔类型,空字符串为 false,包含:truefalse"true""false"""
    • keyword:关键字类型,不进行分词,直接索引,支持模糊、支持精确匹配,支持聚合、排序操作,用于筛选数据。最大支持的长度为——32766 个 UTF-8 类型的字符。
    • number:数字类型,文档链接
      • long
      • integer
      • short
      • byte
      • double
      • float
      • half_float
      • scaled_float
      • unsigned_long
    • Dates:日期类型
      • date:可以是格式化后的日期字符串,也可以是时间戳,例如 2015-01-012015-01-01T12:10:30Z1420070400001
      • date_nanos:支持纳秒的日期格式,在 es 内部是存的长整型
    • alias :别名类型
  • 对象和关系类型
    • object:对象类型,是一个 json 对象
    • flattened:将对象作为单个字段值存储
    • nested:嵌套数据类型,可以看成是一个特殊的对象类型,可以让对象数组独立检索
    • join:同一个文档,但具有父子关系的,类似于树
  • 结构化数据类型
    • range:范围类型,可以用来表示数据的区间
      • integer_range
      • float_range
      • long_range
      • double_range
      • date_range
      • ip_range

日期类型

文档链接

大部分内容来自 链接

JSON 没有日期数据类型,因此 Elasticsearch 中的日期可以是:

date 类型在 Elasticsearch 展示的格式有下面几种:

  • 将日期时间格式化后的字符串,如 "2015-01-01" 或者 "2015/01/01 12:10:30"
  • long 型的整数,意义是 milliseconds-since-the-epoch,翻译一下就是自 1970-01-01 00:00:00 UTC 以来经过的毫秒数。
  • int 型的整数,意义是 seconds-since-the-epoch, 是指自 1970-01-01 00:00:00 UTC 以来经过的秒数。

后两种的描述里都包含 UTC,什么是 UTC 呢?

UTC(Universal Time Coordinated) 叫做世界统一时间,中国大陆和 UTC 的时差是 + 8 ,也就是 UTC+8。

不论 date 是什么展示格式,在 Elasticsearch 内部存储时都是转换成 UTC,并且把时区也会计算进去,从而得到 milliseconds-since-the-epoch 并作为存储的格式。

在查询日期时,会执行下面的过程:

  1. 转换成 long 整形格式的范围 (range) 查询
  2. 得到聚合的结果
  3. 将结果中的 date 类型(long 整型数据)根据 date format 字段转换回对应的展示格式

Date 的默认格式

Date 的格式化类型是可以通过 format 来指定的,如果没有指定,就会使用默认的格式:

"strict_date_optional_time||epoch_millis"

这表示什么意思呢?

先来弄懂 strict_date_optional_time

A generic ISO datetime parser where the date is mandatory and the time is
optional. Full details here.

这是 elasticsearch 官网的解释,表示只要是 ISO datetime parser 可以正常解析的都是 strict_date_optional_time。都有哪些语法呢?

 date-opt-time     = date-element ['T' [time-element] [offset]]
 date-element      = std-date-element | ord-date-element | week-date-element
 std-date-element  = yyyy ['-' MM ['-' dd]]
 ord-date-element  = yyyy ['-' DDD]
 week-date-element = xxxx '-W' ww ['-' e]
 time-element      = HH [minute-element] | [fraction]
 minute-element    = ':' mm [second-element] | [fraction]
 second-element    = ':' ss [fraction]
 fraction          = ('.' | ',') digit+

其中中括号内的都是可选的,可填可不填。以 std-date_element 举个例子

2018-11-19
2018
2018-11

上面 3 种格式都满足要求。

除了 strict_date_optional_time ,还可以是 epoch_millis 格式,即 epoch 以来的毫秒数。

举个例子

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type": "date" 
        }
      }
    }
  }
}

PUT my_index/_doc/1
{ "date": "2015-01-01" } 

PUT my_index/_doc/2
{ "date": "2015-01-01T12:10:30Z" } 

PUT my_index/_doc/3
{ "date": 1420070400001 } 

GET my_index/_search
{
  "sort": { "date": "asc"} 

上面的 PUT 请求中的 date 数据均满足默认的要求。

如何指定多个 date 格式

同一个 date 字段可以指定多个 date 格式,只要使用 || 分隔就可以了。在索引,都会对 date 格式挨个进行匹配,直到找到匹配的格式为止。

如果存储时 date 格式为 milliseconds-since-the-epoch ,在查询时会将其转换为指定的第一个 date 格式。

举个例子,有兴趣的同学可在 sense 中动手实践下。

PUT my_index
{
  "mappings": {
    "doc": {
      "properties": {
        "date": {
          "type":   "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    }
  }
}


PUT /my_index/doc/1
{ "date": "2018-09-24 19:23:45" }


PUT /my_index/doc/2
{ "date": "2018-09-25" }

GET my_index/_search
{
  "query": {
    "match_all": {}
  }
}

date_nanos 类型,支持纳秒

date 类型支持到毫秒,如果特殊情况下用到纳秒得用 date_nanos 这个类型。

和普通的 date 类型一样,可以存 strict_date_optional_time||epoch_millis 这些格式的,不过在 es 内部是存的长整型是纳秒单位的

可以存一个纳秒的试试

PUT my_index/_doc/2
{ "date": "2015-01-01T12:10:30.123456789Z" } 

keyword

keyword 类型字段可以设置 ignore_above 属性 (默认是 10) ,表示最大的字段值长度,超出这个长度的字段将不会被索引,但是会存储。也就是说,如果你超过了这个长度,模糊查询这个字段是查不到的,但查询全部是可以查询到的

别名类型

官方文档

可以给字段起个别名,在搜索的时候可以使用别名搜索

官网示例

PUT trips
{
  "mappings": {
    "properties": {
      "distance": {
        "type": "long"
      },
      "route_length_miles": {
        "type": "alias",
        "path": "distance" 
      },
      "transit_mode": {
        "type": "keyword"
      }
    }
  }
}

GET _search
{
  "query": {
    "range" : {
      "route_length_miles" : {
        "gte" : 39
      }
    }
  }
}

path 就是目标字段的名称,不过有一些限制

  • 目标必须是具体字段,而不是对象或其他字段别名。
  • 创建别名时目标字段必须存在。
  • 如果定义了嵌套对象,则字段别名必须与其目标具有相同的嵌套范围。

字段别名只能指向一个字段,不能同时指向多个字段

不能在写入数据的时候使用字段别名,因为本身字段别名是虚拟的,不存在的,所以不支持写入,同样也不能用于 copy_to

因为字段的别名是不存在 _source中的,所以搜索请求时的过滤字段也是不会生效的

对象类型

object

官方文档

JSON 字符串允许嵌套对象,一个文档可以嵌套多个、多层对象。可以通过对象类型来存储二级文档,不过由于 Lucene 并没有内部对象的概念,ES 会将原 JSON 文档扁平化,例如文档:

PUT my-index-000001/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

实际上 ES 会将其转换为以下格式,并通过 Lucene 存储,即使 name 是 object 类型

{
  "region":             "US",
  "manager.age":        30,
  "manager.name.first": "John",
  "manager.name.last":  "Smith"
}

上面的文档映射关系是

PUT my-index-000001
{
  "mappings": {
    "properties": { 
      "region": {
        "type": "keyword"
      },
      "manager": { 
        "properties": {
          "age":  { "type": "integer" },
          "name": { 
            "properties": {
              "first": { "type": "text" },
              "last":  { "type": "text" }
            }
          }
        }
      }
    }
  }
}

不用设置 type:object,因为这是默认值

flattened

官方文档:链接

可以去看看这篇:CSDN Elasticsearch:Flattened 数据类型映射

默认情况下,对象中的每个子字段都是单独映射和索引的。如果子字段的名称或类型事先不知道,然后动态映射。但 flattened 可以提供其中整个对象映射为单个字段

他将整个对象映射为单个字段。给定一个对象,映射将解析出它的叶子节点的值,并将它们作为关键字索引到一个字段中

为了更好地处理包含大量或未知数量字段的文档而引入的 Elasticsearch 扁平化数据类型 flattened datatype。 默认情况下,Elasticsearch 会在提取文档时自动映射文档中包含的字段。虽然这是开始使用 Elasticsearch 的最简单方法,但随着时间的推移,它往往会导致字段爆炸,并且 Elasticsearch 的性能将受到“内存不足(out of memory)”错误和索引和查询数据时性能不佳的影响。

这种被称为“mapping explosions”的情况实际上很常见。这就是 Flattened 数据类型旨在解决的问题。

官网例子

PUT bug_reports
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "labels": {
        "type": "flattened"
      }
    }
  }
}

POST bug_reports/_doc/1
{
  "title": "Results are not sorted correctly.",
  "labels": {
    "priority": "urgent",
    "release": ["v1.2.5", "v1.3.0"],
    "timestamp": {
      "created": 1541458026,
      "closed": 1541457010
    }
  }
}

如果直接查询顶级节点的话,将会搜索所有叶子节点的值

POST bug_reports/_search
{
  "query": {
    "term": {"labels": "urgent"}
  }
}

如果需要查询对象中特定的属性的话,需要通过对象表达式来查询

POST bug_reports/_search
{
  "query": {
    "term": {"labels.release": "v1.3.0"}
  }
}

查询时,不能使用通配符引用字段键

nested

嵌套数据类型,可以看成是一个特殊的对象类型,可以让对象数组独立检索

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "wu",
      "last" :  "px"
    },
    {
      "first" : "hu",
      "last" :  "xy"
    },
    {
      "first" : "wu",
      "last" :  "mx"
    }
  ]
}

如果 user 是对象数据类型,在内部会转换为

{
  "group" :        "fans",
  "user.first" : [ "wu", "hu", "wu"],
  "user.last" :  [ "px", "xy" ,"mx"]
}

可以看出转换后的 JSON 文档中 first 和 last 的关联丢失了,如果尝试搜索 first 为 wu,last 为 xy 的文档,那么成功会检索出上述文档,但是 wu 和 xy 在原 JSON 文档中并不属于同一个 JSON 对象,应当是不匹配的,即检索不出任何结果。

嵌套类型就是为了解决这种问题的,嵌套类型将数组中的每个 JSON 对象作为独立的隐藏文档来存储,每个嵌套的对象都能够独立地被搜索,所以上述案例中虽然表面上只有 1 个文档,但实际上是存储了 4 个文档。

join

可以去看文章: Elasticsearch:Join 数据类型

在 Elasticsearch 中,Join 可以让我们创建 parent/child 关系。Elasticsearch 不是一个 RDMS。通常 join 数据类型尽量不要使用,除非不得已

例子

PUT my_index
{
  "mappings": {
 "properties": {
   "my_join_field": { 
  "type": "join",
  "relations": {
    "question": "answer" 
  }
   }
 }
  }
}

在这里我们定义了一个叫做 my_index 的索引。在这个索引中,我们定义了一个 field,它的名字是 my_join_field。它的类型是 join 数据类型。同时我们定义了单个关系:question 是 answer 的 parent。

要使用 join 来 index 文档,必须在 source 中提供关系的 name 和文档的可选 parent。例如,以下示例在 question 上下文中创建两个 parent 文档

PUT my_index/_doc/1?refresh
{
  "text": "This is a question",
  "my_join_field": {
 "name": "question" 
  }
}
 
PUT my_index/_doc/2?refresh
{
  "text": "This is another question",
  "my_join_field": {
 "name": "question"
  }
}

这里采用 refresh 来强制进行索引,以便接下来的搜索。在这里 name 标识 question,说明这个文档时一个 question 文档。

索引 parent 文档时,您可以选择仅将关系的名称指定为快捷方式,而不是将其封装在普通对象表示法中:

PUT my_index/_doc/1?refresh
{
  "text": "This is a question",
  "my_join_field": "question" 
}
 
PUT my_index/_doc/2?refresh
{
  "text": "This is another question",
  "my_join_field": "question"
}

例如,以下示例显示如何索引两个 child 文档:

PUT my_index/_doc/3?routing=1?refresh  (1)
{
  "text": "This is an answer",
  "my_join_field": {
 "name": "answer",   (2)
 "parent": "1"       (3)
  }
}
 
PUT my_index/_doc/4?routing=1?refresh
{
  "text": "This is another answer",
  "my_join_field": {
 "name": "answer",
 "parent": "1"
  }
}

在上面的(1)处,我们必须使用 routing,这样能确保 parent 和 child 是在同一个 shard 里。我们这里 routing 为 1,这是因为 parent 的 id 为 1,在(3)处定义。(2) 处定义了该文档 join 的名称。

join 的限制
  • 对于每个 index 来说,只能有一个 join 字段
  • parent 及 child 文档,必须是在一个 shard 里建立索引。这也意味着,同样的 routing 值必须应用于 getting, deleting 或 updating 一个 child 文档。
  • 一个元素可以有多个 children,但是只能有一个 parent.
  • 可以对已有的 join 项添加新的关系
  • 也可以将 child 添加到现有元素,但仅当元素已经是 parent 时才可以。

结构化类型

range

在 Elasticsearch 中有一种数据类型叫做 range 的数据类型。它目前支持的类型如下:

类型 说明
integer_range 一个带符号的 32 位整数范围,最小值为 -2 的 31 次方,最大值为 2 的 31 次方减 1
float_range 一系列单精度 32 位 IEEE 754 浮点值
long_range 一系列带符号的 64 位整数,最小值为 -2 的 63 次方,最大值为 2 的 63 次方 -1
double_range 一系列双精度 64 位 IEEE 754 浮点值。
date_range 自系 EPOCH 以来经过的一系列日期值,表示为无符号的 64 位整数毫秒。
ip_range 支持 IPv4 或 IPv6(或混合)地址的一系列 ip 值。

示例

PUT range_index
{
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "properties": {
      "expected_attendees": {
        "type": "integer_range"
      },
      "time_frame": {
        "type": "date_range", 
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

插入文档

PUT range_index/_doc/1?refresh
{
  "expected_attendees" : { 
    "gte" : 10,
    "lte" : 20
  },
  "time_frame" : { 
    "gte" : "2015-10-31 12:00:00", 
    "lte" : "2015-11-01"
  }
}

gte 是开始,lte是结束,其实就是大于号小于号

查询

GET range_index/_search
{
  "query": {
    "term": {
      "expected_attendees": {
        "value": "10"
      }
    }
  }
}

因为 10 刚好是在我们之前的文档定义的 10-20 区间,所以可以查询到我们刚刚插入的文档文章来源地址https://www.toymoban.com/news/detail-766422.html

到了这里,关于elasticsearch 数据类型详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Elasticsearch与Hbase组合框架的大数据搜索引擎

    本项目为学校大数据工程实训项目,共开发4周,答辩成绩不错。代码仓库放文章尾,写的不好,代码仅供参考。 对于结构化数据 ,因为它们具有特定的结构,所以我们一般都是可以通过关系型数据库(MySQL,Oracle 等)的二维表(Table)的方式存储和搜索,也可以建立索引。

    2024年02月09日
    浏览(65)
  • elasticsearch(ES)分布式搜索引擎04——(数据聚合,自动补全,数据同步,ES集群)

    **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近

    2024年02月08日
    浏览(51)
  • 微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 Sentinel

    聚合(aggregations)可以让我们极其 方便的实现对数据的统计、分析、运算 。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些 统计功能的比数据库的sql要方便的多,而且查询速度非常快 ,可以实现近

    2024年02月11日
    浏览(52)
  • 《Spring Boot 实战派》--13.集成NoSQL数据库,实现Elasticsearch和Solr搜索引擎

             关于搜索引擎 我们很难实现 Elasticseach 和 Solr两大搜索框架的效果;所以本章针对两大搜索框架,非常详细地讲解 它们的原理和具体使用方法, 首先 介绍什么是搜索引擎 、如何用 MySQL实现简单的搜索引擎,以及Elasticseach 的 概念和接口类; 然后介绍Elasticseach

    2023年04月09日
    浏览(91)
  • ES搜索引擎入门+最佳实践(九):项目实战(二)--elasticsearch java api 进行数据增删改查

            本篇是这个系列的最后一篇了,在这之前可以先看看前面的内容: ES搜索引擎入门+最佳实践(一)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(二)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(三)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(四)_flame.liu的博客

    2024年02月12日
    浏览(59)
  • 微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 微服务保护 Sentinel

    聚合(aggregations)可以让我们极其 方便的实现对数据的统计、分析、运算 。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些 统计功能的比数据库的sql要方便的多,而且查询速度非常快 ,可以实现近

    2024年02月15日
    浏览(56)
  • Java SpringBoot API 实现ES(Elasticsearch)搜索引擎的一系列操作(超详细)(模拟数据库操作)

    小编使用的是elasticsearch-7.3.2 基础说明: 启动:进入elasticsearch-7.3.2/bin目录,双击elasticsearch.bat进行启动,当出现一下界面说明,启动成功。也可以访问http://localhost:9200/ 启动ES管理:进入elasticsearch-head-master文件夹,然后进入cmd命令界面,输入npm run start 即可启动。访问http

    2024年02月04日
    浏览(57)
  • 分布式搜索引擎——elasticsearch搜索功能

    Elasticsearch提供了基于JSON的DSL (Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如: match_query multi_match_query 精确查询:根据精确词条

    2024年02月05日
    浏览(68)
  • 分布式搜索引擎ElasticSearch——搜索功能

    DSL查询分类 DSL官方文档 全文检索查询 精确查询 地理查询 复合查询 Function Score Query function score query Boolean Query 排序 分页 官方文档 高亮 快速入门 match,term,range,bool查询 排序和分页 高亮显示 就是在前面抽取的解析代码中进一步添加关于高亮的解析部分,因为highlight和so

    2024年02月01日
    浏览(54)
  • Elasticsearch全文搜索引擎

    Elasticsearch全文搜索引擎 Elasticsearch简介 windows平台下安装ES 学习ES的预备知识 ES索引操作 ES文档操作 ES高级查询 Golang操作ES起步 Golang操作ES索引 Golang操作ES文档 Golang ES高级查询 Gin集成ES

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包