创建索引
使用put命令可以创建索引,并指定索引的分片数和副本数。
PUT 索引名
{
"settings": {
"index": {
"number_of_shards": "8", // 分片数量
"number_of_replicas": "0" // 副本数量
}
}
}
修改索引副本
修改索引副本数量
PUT /索引名/_settings
{
"number_of_replicas": 1 // 副本数量
}
删除索引
delete 索引名
修改索引mapping
首先我们创建一个索引,报错:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true."
}
],
"type": "illegal_argument_exception",
"reason": "Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true."
},
"status": 400
}
这个是因为elasticsearch7.0 之后不支持type导致的。
原因是由于写法是低版本的elasticsearch的,高版本要求传入一个include_type_name参数,值为true。所以加上一个参数即可。include_type_name=true
PUT saas-mall-comment-buyershow/_doc/_mapping?include_type_name=true
{
"properties": {
"wid": {
"type": "long"
},
"operateSource": {
"type": "byte"
},
"userImageUrl": {
"type": "keyword"
},
"userNickname": {
"type": "keyword"
},
"commentInfo": {
"properties": {
"imageContent": {
"properties":{
"url": {
"type": "keyword"
},
"width": {
"type": "long"
},
"height": {
"type": "long"
}
}
},
"textContent": {
"type": "text"
},
"videoContent": {
"properties": {
"imageUrl": {
"type": "keyword"
},
"mediaHeight": {
"type": "long"
},
"mediaName": {
"type": "keyword"
},
"mediaUrl": {
"type": "keyword"
},
"mediaWidth": {
"type": "long"
}
}
}
}
},
"relateGoods": {
"properties": {
"goodsId": {
"type": "long"
}
}
},
"groups": {
"properties": {
"id": {
"type": "long"
}
}
},
"isAnonymity": {
"type": "byte"
},
"isAudit": {
"type": "byte"
},
"isHide": {
"type": "byte"
},
"commentCount": {
"type": "long"
},
"createTime": {
"type": "long"
},
"isSelected": {
"type": "byte"
},
"id": {
"type": "long"
},
"parentId": {
"type": "long"
}
}
}
es中的字段类型
es的索引mapping设置,设置合适的字段type可以增加es的写入速度。
text
会被分词器解析, 生成倒排索引, 支持模糊、精确查询, 不用于排序, 很少用于聚合,常用于全文检索。
"textContent": {
"type": "text"
}
keyword
如果需要为结构化内容, 比如 id、email、hostnames、状态码、标签等进行索引,则推荐使用 keyword 类型以进行完全匹配. 比如我们需要查询"已发货"的订单, 标记为"已发布"的文章等.
"userNickname": {
"type": "keyword"
}
ES会对"数值(numeric)"类型的字段(比如, integer, long)进行优化以支持范围(range)查询. 但是, 不是所有的数值类型的数据都需要使用"数值"类型, 比如产品id, 会员id, ISDN(出版社编号), 这些很少会被进行范围查询, 通常都是精确匹配(term query).
keyword类型的查询通常比numeric的要快, 如果不需要范围查询, 则建议使用keyword类型.
如果不确定使用哪一种, 可以通过multi-field同时设置keyword和numeric类型。
数值类型
- 整型: byte, short, integer, long 这些与java中的类型一致
- 浮点型: float, half_float, scaled_float, double
类型 | 说明 | 取值范围 |
---|---|---|
byte | 8位有符号整数 | -128 ~ 127 |
short | 16位有符号整数 | -32768 ~ 32767 |
integer | 32位有符号整数 | -2,147,483,648 ~ 2,147,483,647 即:-2^31 ~ 2^32 - 1 |
long | 64位有符号整数 | -2^63 ~ 2^63 - 1 |
float | 32位单精度IEEE 754浮点类型, 有限值, 24bits | 2^-149 ~ (2 - 2^-23) · 2^127 |
double | 64位双精度IEEE 754浮点类型, 有限值, 53bits | 2^-1074 ~ (2 - 2^-52) · 2^1023 |
half_float | 16位半精度IEEE 754浮点类型, 有限值, 11bits | 2^-24 ~ 65504 |
scaled_float | 带有缩放因子scaling_factor的浮点数, 可以当整型看待 |
PUT my_index
{
"mappings": {
"properties": {
"number_of_bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
数值类型使用的注意事项:
- 在满足业务需求的情况下, 尽量选择范围小的类型, 这与mysql等关系型数据库的设计要求是一致的. 字段占用的空间越小, 搜索和索引的效率越高.
- 如果是浮点数, 则也要优先考虑使用scaled_float类型.
对于scaled_float类型, 在索引时会乘以scaling_factor并四舍五入到最接近的一个long类型的值.
如果我们存储商品价格只需要精确到分, 两位小数点, 把缩放因子设置为100, 那么浮点价格99.99存储的是9999.
如果我们要存储的值是2.34, 而因子是10, 那么会存储为23, 在查询/聚合/排序时会表现为这个值是2.3. 如果设置更大的因子(比如100), 可以提高精度, 但是会增加空间需求.
scaled_float在查询时的的数据处理应该与mysql类似, 比如: SELECT * FROM products WHERE price > 99.99 * 100, 而不是 SELECT * FROM products WHERE price / 100 > 99.99, 后面一个写法不符合mysql优化原则: 不要对栏位进行函数运算以及类型转换.
Object
JSON文档天生具有层级关系: 文档可能包含内部对象, 而这个对象可能本身又包含对象, 就是可以包含嵌套的对象.
"commentInfo": {
"properties": {
"imageContent": {
"properties":{
"url": {
"type": "keyword"
},
"width": {
"type": "long"
},
"height": {
"type": "long"
}
}
},
"textContent": {
"type": "text"
},
"videoContent": {
"properties": {
"imageUrl": {
"type": "keyword"
},
"mediaHeight": {
"type": "long"
},
"mediaName": {
"type": "keyword"
},
"mediaUrl": {
"type": "keyword"
},
"mediaWidth": {
"type": "long"
}
}
}
}
}
上述,字段commentInfo中包含了图片文字和视频,我们想对文字类型做分词匹配,所以使用了text类型。
在ES内部, 这个文档会被索引成一个扁平的key-value对:
commentInfo.textContent
commentInfo.imageContent.url
...
时间类型
JSON没有日期(date)类型, 在ES中date类型可以表现为:
- 字符串格式的日期, 比如: “2015-01-01”, “2015/01/01 12:10:30”
- long类型的自 epoch (1970-1-1) 以来的毫秒数
- integer类型的自 epoch (1970-1-1) 以来的秒数(时间戳, timestamp)
数组类型
ELasticsearch没有独立的数组类型,默认情况下任何字段都可以包含一个或者多个值,但是数组中的值必须是同一种类型。例如:
- 字符串数组: [ “one”, “two” ]
- 整型数组:[ 1, 2 ]
- 嵌套数组:[ 1, [ 2, 3 ]], 它等价于 [ 1, 2, 3 ]
- 对象数组:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }]