原文链接:https://xiets.blog.csdn.net/article/details/132348634
版权声明:原创文章禁止转载
专栏目录:Elasticsearch 专栏(总目录)
ES 映射字段的 数据类型,官网文档参考:Field data types。
1. 基本数据类型
下面是 ES 常用的一些基本数据类型。
1.1 字符串
字符串 类型:
- keyword:关键字类型。
- text:文本类型。
keyword 类型是不可切分的字符串类型,需要全匹配,用于字符串是否相等的比较。keyword 类型一般用于文档的过滤、排序和聚合。在实际场景用,keyword 一般用于描述 用户名、类型、用户ID、URL 等。
text 类型是可进行分词分隔的字符串类型,支持部分匹配、模糊匹配。由于 text 是模糊匹配,所有支持匹配度打分。text 类型一般用于描述文章标题、文章内容等。
官网相关链接:Keyword type family、Text type family
使用示例:
// 创建索引 PUT /index01 { "mappings": { "properties": { "name": { "type": "keyword" }, "desc": { "type": "text" } } } } // 写入文档 PUT /index01/_doc/001 { "name": "用户名01", "desc": "这是一位大V用户。" }
1.2 数值
数值 类型:
- long长整型。
- integer:整型。
- short:半长整形。
- byte:字节类型。
- float:浮点型。
- double:双精度浮点型。
- half_float:半精度浮点型。
- scaled_float:可伸缩浮点型。
- unsigned_long:无符号长整型。
数值类型支持 相等、范围(大小)比较,也可用于对文档的过滤、排序和聚合。
官网相关链接:Numeric field type
使用示例:
// 创建索引 PUT /index02 { "mappings": { "properties": { "age": { "type": "integer" }, "salary": { "type": "double" } } } } // 写入文档 PUT /index02/_doc/001 { "age": 30, "salary": 99999.99 }
1.3 布尔
布尔类型:
- boolean:布尔类型。
布尔类型的值只有 true 和 false 两种情况的值。
官网相关链接:Boolean field type
使用示例:
// 创建索引 PUT /index03 { "mappings": { "properties": { "is_male": { "type": "boolean" } } } } // 写入文档 PUT /index03/_doc/001 { "is_male": true } PUT /index03/_doc/002 { "is_male": false }
1.4 日期
日期类型:
- date:日期类型。
ES 中存储的日期类型是标准的 UTC 格式。date 类型值的字面表示可以是 格式化的日期时间格式 或 时间戳整数。
date 类型的默认格式为:"strict_date_optional_time||epoch_millis"。其中 strict_date_optional_time 表示格式化日期时间字符串,例如:“yyyy-MM-dd”、“yyyy-MM-ddTHH:mm:ss”、“yyyy-MM-ddTHH:mm:ssZ”、“yyyyMMdd”、“yyyyMMddHHmmss” 等。epoch_millis 表示自纪元以来的毫秒数(时间戳毫秒数)。
date 类型还可以在索引的 mapping 中设置 format 字段自定义格式。如果自定义格式,则后续写入只支持 format 中自定义的格式。
日期类型支持 相等、范围(大小)比较。
官网相关链接:Date field type
使用示例:
// 创建索引 PUT /index04 { "mappings": { "properties": { "create_time": { "type": "date" // 使用默认格式 }, "update_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" // 自定义格式 }, "delete_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" // 可同时支持多种自定义格式 } } } } // 写入文档 PUT /index04/_doc/001 { "create_time": "2023-07-10", "update_time": "2023-07-10 20:30:30" } PUT /index04/_doc/002 { "create_time": "2015-01-01T12:10:30", "delete_time": "2023-01-01 00:00:00" } PUT /index04/_doc/003 { "create_time": 1420070400001, "delete_time": 1420070400001 }
2. 复杂据类型
2.1 数组
ES 数组没有显式的定义方式,基本数据类型的普通字段就可以接收数组类型的值,只需要在写入文档时,把数据用中括号括起来即可。数组字段搜索时也和搜索普通字段一样。
使用示例:
// 创建索引 PUT /book { "mappings": { "properties": { "tag": { // 声明一个关键字类型的 tag 字段 "type": "keyword" } } } } // 写入文档 PUT /book/_doc/001 { "tag": "编程语言" // 写入字段值 } PUT /book/_doc/002 { "tag": ["人工智能", "编程语言"] // 以数组的方式写入值 } // 查看文档 GET /book/_doc/001 // 返回 { "_index": "book", "_id": "001", "_version": 1, "_seq_no": 0, "_primary_term": 1, "found": true, "_source": { "tag": "编程语言" } } GET /book/_doc/002 // 返回 { "_index": "book", "_id": "002", "_version": 1, "_seq_no": 1, "_primary_term": 1, "found": true, "_source": { "tag": [ "人工智能", "编程语言" ] } } // 搜索文档 POST /book/_search { "query": { "term": { "tag": { "value": "编程语言" } } } } // 返回 { "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 0.21110919, "hits": [ { "_index": "book", "_id": "001", "_score": 0.21110919, "_source": { "tag": "编程语言" } }, { "_index": "book", "_id": "002", "_score": 0.21110919, "_source": { "tag": [ "人工智能", "编程语言" ] } } ] } }
2.2 对象
对象类型也没有显示的定义方式,也没有指定的 type 类型值,只需要在定义字段的时候,继续给字段加属性即可。
使用示例:
// 创建索引 PUT /topic { "mappings": { // 映射 "properties": { // 映射的属性 "title": { // 属性1: keyword类型的 title 字段 "type": "keyword" }, "content": { // 属性2: text类型的 content 字段 "type": "text" }, "statistics": { // 属性3: 对象类型的 statistics 字段, 对象有两个属性 "properties": { // 对象的属性 "comment_count": { "type": "integer" }, "like_count": { "type": "integer" } } } } } } // 写入文档 PUT /topic/_doc/001 { "title": "主题标题001", "content": "主题内容001", "statistics": { "like_count": 100, "comment_count": 200 } } // 搜索文档 POST /topic/_search { "query": { "range": { "statistics.like_count": { // 使用 对象.属性 的方式引用属性值 "gte": 100, "lte": 500 } } } } // 返回 { "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 1, "hits": [ { "_index": "topic", "_id": "001", "_score": 1, "_source": { "title": "主题标题001", "content": "主题内容001", "statistics": { "like_count": 100, "comment_count": 200 } } } ] } }
2.3 地理坐标
ES 支持地理位置坐标和形状区域数据类型的存储和搜索。
其中地理坐标存储了经纬度,可以根据位置距离搜索数据。geo_point 类型表示地理坐标类型。
官网相关链接:
- Geopoint field type:地理坐标类型。
- Geoshape field type:地理形状类型。
geo_point 使用示例:
// 创建索引 PUT /hotel { "mappings": { "properties": { "title": { "type": "keyword" }, "location": { // 地理坐标类型的属性 "type": "geo_point" } } } } // 写入文档 PUT /hotel/_doc/001 { "title": "AAA大酒店", "location": { "lat": 22.5369848, // 纬度, 正数表示北纬, 负数表示南纬 "lon": 113.9271766 // 经度, 正数表示东经, 负数表示西经 } } PUT /hotel/_doc/002 { "title": "BBB大酒店", "location": [113.9174415, 22.5352364] // 以数组的形式写入, 格式: [经度, 纬度] } PUT /hotel/_doc/003 { "title": "CCC大酒店", "location": "22.5412263,114.0613099" // 以字符串的形式写入, 格式: "纬度,经度" } // 根据距离搜索 GET /hotel/_search { "query": { "geo_distance": { // 根据距离搜索 "location": { // 中心点 (指定位置坐标), "location" 是 geo_point 类型的字段名称 "lat": 22.5281343, "lon": 113.9321684 }, "distance": "5km" // 搜索距离中心点 5km 范围内的酒店 } } } // 返回 { "took": 3, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 1, "hits": [ { "_index": "hotel", "_id": "001", "_score": 1, "_source": { "title": "AAA大酒店", "location": { "lat": 22.5369848, "lon": 113.9271766 } } }, { "_index": "hotel", "_id": "002", "_score": 1, "_source": { "title": "BBB大酒店", "location": [ 113.9174415, 22.5352364 ] } } ] } }
3. 动态映射
ES 向索引写入文档时,如果相关字段没有在映射中定义,则 ES 会根据写入的数据结构和类型自动扩展映射,这种机制称为动态映射。
动态映射时,JSON 数据类型和索引字段类型的对应关系:
JSON 类型 ES 索引字段类型 null 不增加字段 true 或 false boolean interger long float float object 对象类型 array 根据数组中的第一个非空值决定 string date、double、long、text 都有可能,根据数据格式进行判断 通常在创建索引时,最好先把映射字段的数据类型先定义好,因为 ES 的动态映射生成的字段类型可能会与用户的预期有差别。
4. 多类型(子字段)
针对同一个字段,有时可能需要多种数据类型。比如搜索酒店名称时,有时希望分词模糊搜索,有时又希望全匹配搜索,这时就可以把名称定义为 text 类型,然后再增加多一个 keyword 类型的子字段。
使用示例:
// 创建索引 PUT /hotel { "mappings": { "properties": { "name": { // 字段, 名称为 "name", 类型为 text "type": "text", "fields": { // 定义子字段 "keyword_name": { // 子字段, 名称为 "keyword_name", 类型为 keyword "type": "keyword" } } } } } } // 写入文档 PUT /hotel/_doc/001 { "name": "AAA大酒店" // 只需要写入主字段, 会自动应用到子字段 } PUT /hotel/_doc/002 { "name": "BBB大酒店" } // 搜索文档 POST /hotel/_search { "query": { "match": { // 分词模糊搜索 "name": "酒店" } } } POST /hotel/_search { "query": { "term": { // 使用子字段全匹配搜索 "name.keyword_name": "AAA大酒店" } } }
- date:日期类型。
- boolean:布尔类型。