elasticsearch-文档(三)

 文档

elasticsearch是通过document的形式存储数据的,个人理解文档就是一条数据一个对象

我们添加索引文档中不仅包含了数据还包含了元数据

比如我们为一个数据添加索引

文档中不仅有json的这些属性还包含红框中的值

文档的CRUD

http://127.0.0.1:9200/blogs/product/1 

put 修改或者新增id为1的文档如果不存在新增 如果存在修改(1.找到旧文档json  2.修改他 3.删除旧文档 4.索引新文档)

delete则为删除

elasticsearch乐观锁 

可以发现我们文档元数据有个version字段我们可以利用version字段进行乐观锁

修改失败 我们把版本换成4试试

成功

使用外部版本控制,比如使用我们主数据库表的版本字段添加则使用

http://127.0.0.1:9200/blogs/product/1?version=10&version_type=external

可以看到版本号变成了10  如果再次执行会抱错 因为不大于当前版本号 可以控制并发新增 导致的数据重复

文档局部更新

前面我们看到通过update请求也能实现更新,但是他是覆盖文档,删除原来的文档填入新的文档

post请求:http://127.0.0.1:9200/blogs/product/1/_update

参数

{
   "doc":{
     "productName":"测试修改",
     "videw":1
   }
}

相同字段会被更新 不存在的则添加到文档

使用groovy脚本更新

价格+1

post请求:http://127.0.0.1:9200/blogs/product/1/_update

参数

{
    "script":"ctx._source.price+=1"
}

ctx代表文档_source代表文档中的_source字段,因为我们的数据就是存在文档元数据的_source字段的

{
    "_index": "blogs",
    "_type": "product",
    "_id": "1",
    "_version": 12,
    "_seq_no": 9,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "productName": "测试修改",
        "price": 11,
        "remark": "不错的床垫",
        "tags": [
            "家具",
            "床垫",
            "棉花"
        ],
        "videw": 1
    }
}

往tag中添加一个元素

post请求:http://127.0.0.1:9200/blogs/product/1/_update

参数:

{
    "script":"ctx._source.tag+=newtag",
    "params":{
        "newtag":"测试tag新增"
    }
}

5.*之后会报错 Variable [newtag] is not defined

参数应改为:

{
    "script":"ctx._source.tags.add(params.newtag)",
    "params":{
        "newtag":"测试tag新增"
    }
}

更新不存在的文档

适合计数器

post请求:http://127.0.0.1:9200/blogs/product/2/_update

参数

{
    "script":"ctx._source.count+=1",
    "upsert":{
        "count":"1"
    }
}

第一次请求 将会为文档id为2的创建一个count属性 后续请求+1

更新重试

post请求:http://127.0.0.1:9200/blogs/product/2/_update?retry_on_conflict=5 更新失败后将会重试5此

批量操作

格式:

{
  actionName:{metadata}

  {requestBody}

  .....
}

如我们同时要新增替换文档删除文档局部更新

post请求:http://127.0.0.1:9200/_bulk

{"create":{"_index":"blog","_type":"product","_id":5}}
{"title":{"productName": "批量测试新增5","price": 10,"remark": "不错的床垫","tags": ["家具","床垫","棉花"],"videw": 1}}
{"index":{"_index":"blog","_type":"product","_id":5}}

{"title":{"productName": "批量测试新增","price": 10,"remark": "不错的床垫","tags": ["家具","床垫","棉花"],"videw": 1}}
{"update":{"_index":"blog","_type":"product","_id":1,"_retry_on_conflict":3}}
{"doc":{"title":{"productName": "批量测试修改" }}}
{"delete":{"_index":"blog","_type":"product","_id":5}}}}

注意最后一个json需要有一个换行符

create创建文档 不存在则新增

index 创建文档不存在新增 存在覆盖

update 局部更新

delete删除

响应结果:

{
    "took": 7,
    "errors": true,
    "items": [
        {
            "create": {
                "_index": "blog",
                "_type": "product",
                "_id": "5",
                "status": 409,
                "error": {
                    "type": "version_conflict_engine_exception",
                    "reason": "[product][5]: version conflict, document already exists (current version [2])",
                    "index_uuid": "CZ6SoctfQcCzXmVXFLdDuA",
                    "shard": "1",
                    "index": "blog"
                }
            }
        },
        {
            "index": {
                "_index": "blog",
                "_type": "product",
                "_id": "5",
                "_version": 3,
                "result": "updated",
                "_shards": {
                    "total": 2,
                    "successful": 1,
                    "failed": 0
                },
                "_seq_no": 2,
                "_primary_term": 1,
                "status": 200
            }
        },
        {
            "update": {
                "_index": "blog",
                "_type": "product",
                "_id": "1",
                "status": 404,
                "error": {
                    "type": "document_missing_exception",
                    "reason": "[product][1]: document missing",
                    "index_uuid": "CZ6SoctfQcCzXmVXFLdDuA",
                    "shard": "3",
                    "index": "blog"
                }
            }
        },
        {
            "delete": {
                "_index": "blog",
                "_type": "product",
                "_id": "5",
                "_version": 4,
                "result": "deleted",
                "_shards": {
                    "total": 2,
                    "successful": 1,
                    "failed": 0
                },
                "_seq_no": 3,
                "_primary_term": 1,
                "status": 200
            }
        }
    ]
}

不需要重复指定所以呢和type可以在url带上索引和type上面就不用指定索引和type了

批量操作都是独立的并不是原子的 互不影响 

索引文档原理

新建索引和删除文档

write操作都必须在主节点完成

1:请求到note1  操作P0分片数据

2.确定根据id shard=hash(routing)%number_of_parimary_shard 求出余数算出分片位置  转发请求到node3

3.node3执行请求 如果成功 复制分片在node1和node2 索引转发请求到node1和node2 如果都成功则修改生效

replication参数

第3步骤转发请求到复制分片是同步的 可以通过设置replication为async 则为异步  但是数据的准确性得不到保证 而且会导致每个请求都不等待复制返回 而导致的请求过载(不建议使用)、

consistency参数

在写入时必须有规定数量的分片可用才能写入 公式:

5.*以上貌似移除

timeout参数

分片副本不足的等待时间 默认一分钟

检索文档

1.node1接收到检索P0分片的请求

2.因为P0分片数据 在3个节点都存在 

3.保证性能会通过负载均衡算法 算出转发到对应的节点

局部更新

1.node1接收到修改p0分片数据

2.转发到node3节点

3.node3节点 将分片文档的_source进行替换并重做索引

4.将请求转发大node1和node2处理 因为复制分片存放在node1和node2

根据条件更新

api地址:https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs-update-by-query.html

post:http://127.0.0.1:9200/[indexName]/_update_by_query

{
    "query": {
        "bool": {
            "must": [{
                "term": {
                    "_id": "11"
                }
            }]
        }
    },
    "script": {
        "inline": "ctx._source.name = params.name",
        "params": {
            "tags": "dd"
        },
        "lang": "painless"

    }
}

使用java api写法

 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                boolQueryBuilder.must().add(QueryBuilders.termQuery("mdProductId", productCharacterStocksVo.getProductId()));
                boolQueryBuilder.must().add(QueryBuilders.termQuery("characterId", productCharacterStocksVo.getCharacterId()));
                boolQueryBuilder.must().add(QueryBuilders.termQuery("regionCode", productCharacterStocksVo.getRegionCode()));
                boolQueryBuilder.must().add(QueryBuilders.termQuery("ladingFactoryId", productCharacterStocksVo.getFactoryId()));
                updateByQueryRequest.setQuery(boolQueryBuilder);
                updateByQueryRequest.setScript(new Script(
                        ScriptType.INLINE, "painless",
                        "ctx._source.stockCount=" + productCharacterStocksVo.getSumCount(),
                        Collections.emptyMap()));
                try {
                    log.info(updateByQueryRequest.toString());
                    BulkByScrollResponse bulkByScrollResponse = eshlRestUtil.getClient().updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
                    count = bulkByScrollResponse.getUpdated();
                }catch (Exception e){
                    e.printStackTrace();
                    count=0L;
                }

根据条件删除

post:http://127.0.0.1:9200/test_latest/_delete_by_query

{
    "query": {
        "bool": {
            "must": [{
                "term": {
                    "_id": "11"
                }
            }]
        }
    }
}
原文地址:https://www.cnblogs.com/LQBlog/p/10427414.html