zoukankan      html  css  js  c++  java
  • 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"
                    }
                }]
            }
        }
    }
  • 相关阅读:
    docker技术快速实现前后端项目的集群化⑥基于haproxy创建pxc集群的负载均衡
    docker技术快速实现前后端项目的集群化⑤docker环境下搭建percona-mysql的pxc集群
    docker技术快速实现前后端项目的集群化④linux基础防火墙命令和docker的安装部署
    docker技术快速实现前后端项目的集群化③renren-fast前端nodejs环境在windows下的搭建
    docker技术快速实现前后端项目的集群化②renren-fast后端java环境在eclipse中windows环境的搭建
    docker技术快速实现前后端项目的集群化①java项目在windows下maven环境的搭建
    docker技术快速实现前后端项目的集群化概述
    基于centos的docker基础镜像制作有jdk1.8的java环境镜像
    docker容器的ubuntu系统中设置apt-get代理和apt-get源
    centos7环境下php网站通过webshell安全扫描工具对系统做检测
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10427414.html
Copyright © 2011-2022 走看看