1、elasticsearch的数据类型
1.1、核心数据类型
1.1.1、字符串类型(string不再支持)
当一个字段需要用于全文搜索(会被分词), 比如产品名称、产品描述信息, 就应该使用text类型.
text的内容会被分词, 可以设置是否需要存储: “index”: “true|false”.
text类型的字段不能用于排序, 也很少用于聚合.
PUT website
{"mappings": {"blog": {"properties": {"summary": {"type": "text", "index": "true"}}}}
}
当一个字段需要按照精确值进行过滤、排序、聚合等操作时, 就应该使用keyword类型.
keyword的内容不会被分词, 可以设置是否需要存储: “index”: “true|false”.
PUT website
{"mappings": {"blog": {"properties": {"tags": {"type": "keyword", "index": "true"}}}}
}
1.1.2 数字类型
类型 | 说明 |
---|---|
byte | 有符号的8位整数, 范围: [-128 ~ 127] |
short | 有符号的16位整数, 范围: [-32768 ~ 32767]nteger |
integer | 有符号的32位整数, 范围: [−231 ~ 231-1] |
long | 有符号的64位整数, 范围: [−263 ~ 263-1] |
float | 32位单精度浮点数 |
double | 64位双精度浮点数 |
half_float | 16位半精度IEEE 754浮点类型 |
scaled_float | 缩放类型的的浮点数, 比如price字段只需精确到分, 57.34缩放因子为100, 存储结果为5734 |
PUT shop
{"mappings": {"book": {"properties": {"name": {"type": "text"},"quantity": {"type": "integer"}, // integer类型"price": {"type": "scaled_float", // scaled_float类型"scaling_factor": 100}}}}
}
1.1.3 日期类型 - date
JSON没有日期数据类型, 所以在ES中, 日期可以是:
包含格式化日期的字符串, “2018-10-01”, 或"2018/10/01 12:10:30".
代表时间毫秒数的长整型数字.
代表时间秒数的整数.
// 添加映射
PUT website
{"mappings": {"blog": {"properties": {"pub_date": {"type": "date"} // 日期类型}}}
}// 添加数据
PUT website/blog/11
{ "pub_date": "2018-10-10" }PUT website/blog/12
{ "pub_date": "2018-10-10T12:00:00Z" } // Solr中默认使用的日期格式PUT website/blog/13
{ "pub_date": "1589584930103" }
1.2、复杂数据类型
1.2.1 数组类型 - array
ES中没有专门的数组类型, 直接使用[]定义即可;
数组中所有的值必须是同一种数据类型, 不支持混合数据类型的数组:
① 字符串数组: [“one”, “two”];
② 整数数组: [1, 2];
③ 由数组组成的数组: [1, [2, 3]], 等价于[1, 2, 3];
④ 对象数组: [{“name”: “Tom”, “age”: 20}, {“name”: “Jerry”, “age”: 18}].
- 动态添加数据时, 数组中第一个值的类型决定整个数组的类型;
- 不支持混合数组类型, 比如[1, “abc”];
- 数组可以包含null值, 空数组[]会被当做missing field —— 没有值的字段
1.2.2 对象类型 - object
JSON文档是分层的: 文档可以包含内部对象, 内部对象也可以包含内部对象.
# 添加示例
PUT employee/developer/1
{"name": "ma_shoufeng","address": {"region": "China","location": {"province": "GuangDong", "city": "GuangZhou"}}
}
# 存储方式
{"name": "ma_shoufeng","address.region": "China","address.location.province": "GuangDong", "address.location.city": "GuangZhou"
}# 文档的映射结构
PUT employee
{"mappings": {"developer": {"properties": {"name": { "type": "text", "index": "true" }, "address": {"properties": {"region": { "type": "keyword", "index": "true" },"location": {"properties": {"province": { "type": "keyword", "index": "true" },"city": { "type": "keyword", "index": "true" }}}}}}}}
}
1.2.3 嵌套类型 - nested
嵌套类型是对象数据类型的一个特例, 可以让array类型的对象被独立索引和搜索.
对象数组是如何存储的
# 添加数据:
PUT game_of_thrones/role/1
{"group": "stark","performer": [{"first": "John", "last": "Snow"},{"first": "Sansa", "last": "Stark"}]
}
# 内部存储结构:
{"group": "stark","performer.first": [ "john", "sansa" ],"performer.last": [ "snow", "stark" ]
}
# 存储分析:
可以看出, user.first和user.last会被平铺为多值字段, 这样一来, John和Snow之间的关联性就丢失了.
在查询时, 可能出现John Stark的结果.
用nested类型解决object类型的不足
如果需要对以最对象进行索引, 且保留数组中每个对象的独立性, 就应该使用嵌套数据类型.
—— 嵌套对象实质是将每个对象分离出来, 作为隐藏文档进行索引.
# 创建映射
PUT game_of_thrones
{"mappings": {"role": {"properties": {"performer": {"type": "nested" }}}}
}# 添加数据
PUT game_of_thrones/role/1
{"group" : "stark","performer" : [{"first": "John", "last": "Snow"},{"first": "Sansa", "last": "Stark"}]
}# 检索数据
GET game_of_thrones/_search
{"query": {"nested": {"path": "performer","query": {"bool": {"must": [{ "match": { "performer.first": "John" }},{ "match": { "performer.last": "Snow" }} ]}}, "inner_hits": {"highlight": {"fields": {"performer.first": {}}}}}}
}
参考资料
- https://www.cnblogs.com/shoufeng/p/10692113.html es数据类型讲的很详细;