binary类型存储字符串base64处理之后的值
json格式没有date类型,ES中表示date类型的有以下三种:
1)、字符串格式,如’2020-01-01’或’2020/05/26 09:45:00’;
2)、long类型数值,表示从毫秒开始的计数;
3)、integer类型数值,表示从秒开始的计数;
内部date会转换成UTC时间并以毫秒表示其值;
日期查询会在内部转换为long类型形式的范围查询,并且聚合和存储字段的结果将转换为字符串(具体取决于该字段的日期转换格式);
日期将始终以字符串形式呈现,即使一开始在JSON文档中提供的类型为long;
//date类型字段定义
PUT /date_index_demo
{
"mappings": {
"properties": {
"date":{
"type": "date"
}
}
}
}
PUT /date_index_demo/_doc/1
{
"date":"2020-01-01"
}
PUT /date_index_demo/_doc/2
{
"date":"2020-01-01T12:00:00Z"
}
PUT /date_index_demo/_doc/3
{
"date":"2020-01-01T12:00:00"
}
PUT /date_index_demo/_doc/4
{
"date":1420070400001
}
//排序查询,内部会转为long类型进行处理
GET /date_index_demo/_search
{
"sort": [
{
"date": {
"order": "asc"
}
}
]
}
日期的多种格式化形式
可以使用||分隔符指定多种日期格式,es会依次尝试每种格式,直到找到匹配的格式,将日期格式转换成字符串会优先使用第一种格式转化;
PUT /date_index_demo
{
"mappings": {
"properties": {
"date":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
}
}
}
}
存在的约束:
1)、一个索引当中仅允许一个join类型的映射;
2)、父文档与子文档一定要在同一个分片之上,这就意味着在做get/delete/update操作的时候需要指定相同的routing值;
3)、一个元素可以有多个子级,只允许有一个父级;
4)、允许在join类型的字段上添加一个新的关系;
5)、允许在一个元素中添加一个子级(要求元素需要存在父级);
使用父级join查询
父级join查询及聚合操作
参考has_child和has_parent查询,children聚合及inner hits;
join标识字段可以使用聚合和脚本查询,也可以使用parent_id查询;
同一父级对应多个子级
针对类似于ID、邮箱、域名、状态、邮政编码和标签之类的表示字段,在查询操作时以精确值作为条件,同时可作为排序和聚合操作;
如果针对文本内容做全文索引,使用text字段表示更合适;
数值数据不一定需要用数值类型来表示,若不用于range查询则可以使用keyword代替,因为keyword类型字段针对term或term-level的查询更加友好;
考虑将字段设置成keyword类型可考虑以下因素:
1)、针对该字段有没有range操作的需求;
2)、查询效率上的考虑,因为字段类型为keyword相比数值类型效率更高;
nested类型是object类型的一种特殊形式,其允许对象数组被索引且可以独立进行查询;
es没有内部对象的概念,因此其将对象继承结构转成简单的key-value的list结构;
PUT /nested_type_index/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}
自动映射会自动将user添加为object类型,内部会将文档转成以下格式:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
这种情况下会将user.first和user.last转化成多值字段,这样会导致alice与white之间的关联关系丢失,从而造成查询时结果的不准确:
GET /nested_type_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "Smith"
}
}
]
}
}
}
使用nested字段表示对象数组
可以表示对象数组同时能够保证数组中的对象相互独立,内部将数组中对象看做不同的doc,这就表示可以针对这些对象可使用nested query进行独立查询;
PUT /nested_type_index_1
{
"mappings": {
"properties": {
"user":{
"type": "nested"
}
}
}
}
PUT /nested_type_index_1/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}
//查看映射字段类型
GET /nested_type_index_1/_mapping
//
GET /nested_type_index_1/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "Smith"
}
}
]
}
}
}
GET /nested_type_index_1/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "White"
}
}
]
}
},
"inner_hits": {
"highlight": {
"fields": {
"user.first": {
}
}
}
}
}
}
}
文档字段类型为nested的可行操作:
1)、使用nested查询;
2)、使用nested和reverse_nested聚合查询;
3)、使用nested sorting进行排序;
4)、使用nested inner hits进行检索或高亮匹配;
nested类型映射及对象的限制
因为nested对象在Lucene中是以单独的文档进行索引的,故而若一个索引结构中存在nested类型字段且索引时nested类型字段对应有100个,这时Lucene会创建101个doc;因为nested类型关联代价比较大,es提供以下配置解决性能问题:
序号 | 参数 | 说明 |
---|---|---|
1 | index.mapping.nested_fields.limit | 限制nested类型字段数量 |
2 | index.mapping.nested_objects.limit | 限制nested类型字段可包含的对象数量 |
序号 | 类型 | 范围 |
---|---|---|
1 | long | -2^63 ~ 2^63-1 |
2 | integer | -2^31 ~ 2^31-1 |
3 | short | -32768 ~ 32767 |
4 | byte | -128 ~ 127 |
5 | double | 64位精度 |
6 | float | 32位精度 |
7 | half_float | 16位精度 |
8 | scaled_float | 可配置scaling_factor参数 |
PUT numeric_type_index
{
"mappings": {
"properties": {
"number_of_bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
range类型细分有:integer_range、float_rangellong_range、double_range、date_range、ip_range
//索引定义
PUT range_type_index
{
"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_type_index/_doc/1
{
"expected_attendees":{
"gte":10,
"lte":20
},
"time_frame":{
"gte":"2020-05-28 12:00:00",
"lte":"2020-07-01"
}
}
GET /range_type_index/_search
{
"query": {
"term": {
"expected_attendees": {
"value": 20
}
}
}
}
GET /range_type_index/_search
{
"query": {
"range": {
"time_frame": {
"gte": "2020-05-29",
"lte": "2020-06-01",
"relation":"contains"
}
}
}
}
适用于全文索引,text类型的字段会首先被分词器解析成一个个词元(term),然后才被索引;若一个字段既想作为text类型又想作为keyword类型,可以使用多字段映射进行处理;
PUT token_count_type_index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"length": {
"type": "token_count",
"analyzer": "standard"
}
}
}
}
}
}
PUT token_count_type_index/_doc/1
{
"name":"John Smith"
}
PUT token_count_type_index/_doc/2
{
"name":"Rachel Alice Williams"
}
GET token_count_type_index/_search
{
"query": {
"term": {
"name.length": {
"value": 3
}
}
}
}