在上篇文章写了关于elasticsearch索引的数据类型,这里就详细说下索引的增删改查以及其他的一些操作吧。
先新建一个索引结构,代码如下
PUT test-3-2-1
{
"mappings": {
"properties": {
"id": {
"type": "integer"
},
"sex": {
"type": "boolean"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"born": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"location": {
"type": "geo_point"
}
}
}
}
POST test-3-2-1/_doc/1
{
"id": "1",
"sex": true,
"name": "张三",
"born": "2020-09-18 00:02:20",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
注意:test-3-2-1/_doc/1,在增加的请求中,_doc表示索引的type,1表示_id,代表主键的意思,如果存在就会被覆盖。
GET test-3-2-1/_doc/1
POST test-3-2-1/_update/1
{
"doc": {
"sex": false,
"born": "2020-02-24 00:02:20"
}
}
DELETE test-3-2-1/_doc/1
POST test-3-2-1/_bulk
{"index":{"_id":"3"}}
{"id":"3","name":"王五","sex":true,"born":"2020-09-14 00:02:20","location":{"lat":11.12,"lon":-71.34}}
{"index":{"_id":"4"}}
{"id":"4","name":"李四","sex":false,"born":"2020-10-14 00:02:20", "location":{"lat":11.12,"lon":-71.34}}
{"index":{"_id":"5"}}
{"id":"5","name":"黄六","sex":false,"born":"2020-11-14 00:02:20", "location":{"lat":11.12,"lon":-71.34}}
这样可以批量写入,通过index值,如果已经存在,会覆盖。
索引的重建,先创建一个索引以及分片规则,然后就可以进行移动了
PUT newindex-3-1-3
{
"settings": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
}
POST _reindex
{
"source": {
"index": "test-3-2-1"
},
"dest": {
"index": "newindex-3-1-3"
}
}
低版本的Elasticsearch使用了_version字段来实现乐观锁,在Elasticsearch 7.9.1中使用_version进行并发控制会报错。它提供了两个新的字段_seq_no和_primary_term一起来实现乐观锁。假如你查出主键为1的文档的当前_seq_no为26、_primary_term为3,他是内置的,而且要两个参数一起判断才可以。
PUT test-3-2-1/_doc/1?if_seq_no=26&if_primary_term=3
{
"id": "1",
"sex": false,
"name": "张三",
"born": "2020-09-11 00:02:20",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
想象这样一种场景,假如有一个索引只有一个主分片,但是时间久了以后数据量越来越大,你决定为索引扩容,可是又不愿意重建索引。一个解决问题的办法就是,你可以创建一个新的索引保存新的数据,然后取一个别名同时指向这两个索引,这样在检索时使用别名就可以同时检索到两个索引的数据。
先来新建两个索引logs-1和logs-2并添加数据。
POST logs-1/_doc/10001
{
"visittime": "10:00:00",
"keywords": "[世界杯]",
"rank": 18,
"clicknum": 13,
"id": 10001,
"userid": "2982199073774412",
"key": "10001"
}
POST logs-2/_doc/10002
{
"visittime": "11:00:00",
"keywords": "[奥运会]",
"rank": 11,
"clicknum": 2,
"id": 10002,
"userid": "2982199023774412",
"key": "10002"
}
添加一个索引别名logs指向这两个索引。
POST /_aliases
{
"actions": [
{
"add": {
"index": "logs-1",
"alias": "logs"
}
},
{
"add": {
"index": "logs-2",
"alias": "logs"
}
}
]
}
查看刚才创建的别名logs包含哪些索引,可以用下面的代码
GET _alias/logs
如果要删除索引logs-1的别名,可以使用以下代码。
POST /_aliases
{
"actions" : [
{ "remove": { "index" : "logs-1", "alias" : "logs" } }
]
}
使用正则添加别名,以logs开头的索引都为别名
POST /_aliases
{
"actions" : [
{ "add" : { "index" : "logs*", "alias" : "logs" } }
]
}
配合使用别名和数据过滤可以达到类似于数据库视图的效果,可以把查询条件放入别名,这样在搜索别名时会自动带有查询条件,能起到数据自动过滤的作用。例如:
POST /_aliases
{
"actions": [
{
"add": {
"index": "logs*",
"alias": "logs",
"filter": {
"range": {
"clicknum": {
"gte": 10
}
}
}
}
}
]
}
滚动索引当有一个索引数据量太大时,如果继续写入数据可能会导致分片容量过大,查询时会因内存不足引起集群崩溃。为了避免所有的数据都写入同一个索引,可以考虑使用滚动索引。滚动索引需要配合索引别名一起使用,可实现把原先写入一个索引的数据自动分发到多个索引中。
先创建一个索引log1,它有一个别名logs-all。
PUT /log1
{
"aliases": {
"logs-all": {}
}
}
然后使用别名往log1中写入数据。
PUT logs-all/_doc/1?refresh
{
"visittime": "10:00:00",
"keywords": "[世界杯]",
"rank": 18,
"clicknum": 13,
"id": 10001,
"userid": "2982199073774412",
"key": "10001"
}
PUT logs-all/_doc/2?refresh
{
"visittime": "11:00:00",
"keywords": "[杯]",
"rank": 20,
"clicknum": 12,
"id": 1121,
"userid": "298219d9073774412",
"key": "2"
}
现在来为别名logs-all指定一个滚动索引,如果条件成立,就把新数据写入log2。
POST /logs-all/_rollover/log2
{
"conditions": {
"max_age": "7d",
"max_docs": 1,
"max_size": "5gb"
}
}
上面的滚动索引配置的条件是,如果往别名logs-all中写入的索引数据量大于等于1,或者主分片总大小超过5GB,或者创建索引的时间长度超过7天,就把新的数据写入新索引log2。该请求会返回滚动索引的执行结果,结果如下。
我们也可以自动向下滚动
PUT /log-000001
{
"aliases": {
"logseries": {}
}
}
POST /logseries/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1,
"max_size": "5gb"
}
}