美文网首页
016.Elasticsearch文档管理操作

016.Elasticsearch文档管理操作

作者: CoderJed | 来源:发表于2020-06-30 15:44 被阅读0次

1.1 创建测试用index

curl -X PUT "node01:9200/nba"

curl -X PUT "node01:9200/nba" -H 'Content-Type:application/json' -d'
{
    "mappings": {
        "_doc": {
            "properties": {
                "jerse_no": {
                    "type": "keyword"
                },
                "name": {
                    "type": "text"
                },
                "play_year": {
                    "type": "keyword"
                },
                "position": {
                    "type": "keyword"
                },
                "team_name": {
                    "type": "text"
                },
                "country": {
                    "type": "keyword"
                }
            }
        }
    }
}
'

1.2 自动创建索引

当向一个不存在的index中添加document时,可以自动创建索引,也可以根据传入的数据自动创建mapping,ES也会自动对这些文档进行倒排索引

# 查看ES集群配置
curl -X GET "node01:9200/_cluster/settings"

{
    "persistent":{},
    "transient":{}
}

# 设置自动创建index功能
curl -X PUT "node01:9200/_cluster/settings" -H 'Content-Type:application/json' -d'
{
    "persistent": {
        "action.auto_create_index": "false"
    }
}
'

{   "acknowledged":true,
    "persistent":{
        "action":{
            "auto_create_index":"false"
        }
    },
    "transient":{}
}

当把action.auto_create_index设置成false后,就不可以向不存在的index插入数据了

1.2 添加document

# 手动指定id
curl -X PUT "node01:9200/nba/_doc/1" -H 'Content-Type:application/json' -d'
{
    "name":"哈登",
    "team_name":"火箭",
    "position":"得分后卫",
    "play_year":"10",
    "jerse_no":"13",
    "country": "美国"
}
'
# 也可以让ES自动生成id,不指定id要使用POST请求
curl -X POST "node01:9200/nba/_doc" -H 'Content-Type:application/json' -d'
{
    "name":"库里",
    "team_name":"勇士",
    "position":"控球后卫",
    "play_year":"10",
    "jerse_no":"13",
    "country": "美国"
}
'

# 可以手动指定操作类型
# 指定操作类型时,必须手动设置id
# 当不指定操作时,假如原来已经有id=2的document,那么执行以下操作就会把原来的覆盖掉
# 而指定操作为"create",那么当id=2的document已经存在时,就会报错
curl -X POST "node01:9200/nba/_doc/2?op_type=create" -H 'Content-Type:application/json' -d'
{
    "name":"姚明",
    "team_name":"火箭",
    "position":"中锋",
    "play_year":"9",
    "jerse_no":"11",
    "country": "中国"
}
'

自动设置id与手动设置id的比较:

  • 手动设置id

一般来说,从其他外部系统导入数据到es时,会采取这种方式,使用外部系统中已有数据的唯一标识,作为document的id,例如数据从MySQL导入到ES中,就可以直接使用MySQL表中自己的id

  • 自动生成id

自动生成的id,长度为20个字符,URL安全,base64编码,使用GUID算法可以保证在并行生成id时也不会发生冲突,在直接往ES中写数据的时候,可以使用这种方式

1.3 查看文档

查看单个文档

curl -X GET "node01:9200/nba/_doc/1"

{
    "_index":"nba",
    "_type":"_doc",
    "_id":"1",
    "_version":1,
    "_seq_no":0,
    "_primary_term":1,
    "found":true,
    "_source": {
        "name":"哈登",
        "team_name":"火箭",
        "position":"得分后卫",
        "play_year":"10",
        "jerse_no":"13",
        "country": "美国"
    }
}

文档元数据解析:

  • _index:此文档属于哪个index
  • _type:此文档属于哪个type
  • _id:此文档的id
  • _version:此文档的版本号,ES基于此版本进行并发控制
  • _source:此文档的数据内容

指定返回结果的字段:

curl -X GET "node01:9200/nba/_doc/1?_source=name,country"

{
    "_index":"nba",
    "_type":"_doc",
    "_id":"1",
    "_version":1,
    "_seq_no":0,
    "_primary_term":1,
    "found":true,
    "_source": {
        "name":"哈登",
        "country": "美国"
    }
}

查看多个文档

curl -X POST "node01:9200/_mget" -H 'Content-Type:application/json' -d'
{
    "docs": [
        {
            "_index": "nba",
            "_type": "_doc",
            "_id": "1"
        },
        {
            "_index": "nba",
            "_type": "_doc",
            "_id": "2"
        }
    ]
}
'

curl -X POST "node01:9200/nba/_mget" -H 'Content-Type:application/json' -d'
{
    "docs": [
        {
            "_type": "_doc",
            "_id": "1"
        },
        {
            "_type": "_doc",
            "_id": "2"
        }
    ]
}
'

curl -X POST "node01:9200/nba/_doc/_mget" -H 'Content-Type:application/json' -d'
{
    "docs": [
        {
            "_id": "1"
        },
        {
            "_id": "2"
        }
    ]
}
'

curl -X POST "node01:9200/nba/_doc/_mget" -H 'Content-Type:application/json' -d'
{
    "ids": ["1", "2"]
}
'

说明:

mget是很重要的,查询的时候,如果一次性要查询多条数据的话,那么一定要用mget,尽可能减少网络开销次数,这样可以大幅提升查询性能

1.4 修改文档

# 方法一:直接覆盖原文档
# 但是要列出所有的field,即使这个field不修改
# 否则新的文档就不包含你没有写的那个field了
# 当然,如果就是要删除这个字段,就不用写了
curl -X PUT "node01:9200/nba/_doc/1" -H 'Content-Type:application/json' -d'
{
    "name":"大胡子",
    "team_name":"火箭",
    "position":"得分后卫",
    "play_year":"9",
    "jerse_no":"13",
    "country": "美国"
}
'

# 方法二:修改指定的字段
curl -X POST "node01:9200/nba/_doc/1/_update" -H 'Content-Type:application/json' -d'
{
    "doc": {
        "name":"登哥"
    }
}
'
# ES7.x
curl -X POST "node01:9200/nba/_update/1" -H 'Content-Type:application/json' -d'
{
    "doc": {
        "name":"登哥"
    }
}
'

# 增加一个字段
curl -X POST "node01:9200/nba/_doc/1/_update" -H 'Content-Type:application/json' -d'
{
    "script": "ctx._source.age=18"
}
'
# ES7.x
curl -X POST "node01:9200/nba/_update/1" -H 'Content-Type:application/json' -d'
{
    "script": "ctx._source.age=18"
}
'

# 删除一个字段
curl -X POST "node01:9200/nba/_doc/1/_update" -H 'Content-Type:application/json' -d'
{
    "script": "ctx._source.remove(\"age\")"
}
'
# ES7.x
curl -X POST "node01:9200/nba/_update/1" -H 'Content-Type:application/json' -d'
{
    "script": "ctx._source.remove(\"age\")"
}
'

# 根据参数值,更新字段,要求文档存在并且修改的field存在
curl -X POST "node01:9200/nba/_doc/1/_update" -H 'Content-Type:application/json' -d'
{
    "script": "ctx._source.age+=params.age",
    "params": {
        "age": 4
    }
}
'
# 根据参数值,更新字段,如果文档不存在,新创建一个文档,并且将upsert中的数据插入到该文档中
curl -X POST "node01:9200/nba/_doc/3/_update" -H 'Content-Type:application/json' -d'
{
    "script": {
        "source": "ctx._source.age+=params.age",
        "params": {
            "age": 4
        }
    },
    "upsert": {
        "age": 10
    }
}
'

说明:

修改一个文档的某个字段,在ES的底层,其实也是全量替换,将原来的文档标记为delete状态,新插入一条数据,根据客户端传入的字段加上原数据的其他字段组成了一条新的文档,只不过,这些操作都在shard内部去做了,相比于让用户执行全量替换的操作,优化了网络传输开销,减少了查询和修改的时间开销,提升了性能。

这是Elasticsearch的一个重要特性,即数据是不可变的,更新和删除都是插入一条新的数据同时把旧数据标记为"delete"状态,这样就带来了以下好处:

  • 不需要锁,提升并发能力,避免锁的问题
  • 数据不变,一直保存在os cache中,只要cache内存足够
  • 数据可以压缩,节省CPU和IO开销

1.5 删除文档

curl -X DELETE "node01:9200/nba/_doc/3"

1.6 批量增删改查

语法:

POST /_bulk
{"delete": {"_index": "index_name", "_type": "type_name", "_id": 1}}
{"create": {"_index": "index_name", "_type": "type_name", "_id": 4}}
{"doc": {"field": "value"}}
{"create": {"_index": "index_name", "_type": "type_name", "_id": 5}}
{"doc": {"field1": "value1", "field2": "value2"}}
{"update": {"_index": "index_name", "_type": "type_name", "_id": 1, "some_properties": "properties_value"}}
{"doc": {"field": "value"}}

# 例如:
POST /_bulk
{"delete": {"_index": "user", "_type": "_doc", "_id": 5}}
{"create": {"_index": "user", "_type": "_doc", "_id": 6}}
{"doc": {"uid": "1006", "uname": "Nancy"}}
{"index": {"_index": "shop", "_type": "product", "_id": 5}}
{"doc": {"name": "Gaolujie Toothpaste"}}
{"update": {"_index": "user", "_type": "_doc", "_id": 1, "retry_on_conflict": 3}}
{"doc": {"name": "Nancy"}}

bulk api对json的语法有严格的要求,每个json串不能换行,只能放一行,同时一个json串和一个json串之间,必须换行,除"delete"操作外,每个操作要两个json串,语法如下:

{"action": {"metadata"}}
{"data"}

# action包括:
delete:删除一个文档,只要1个json串就可以了
create:PUT /index/type/id/_create,强制创建
index:普通的put操作,可以是创建文档,也可以是全量替换文档
update:更新操作

任意一个操作失败,不会影响其他操作,但是在返回结果里,会告诉你哪个操作失败了及其错误信息

批量操作会将所有请求加载到内存中,一次请求过多的话,性能反而会下降,一般从5000-1W条数据开始测试,以得到一个最佳性能,同时,一般来说,将一次请求的大小在5-15MB之间

为什么批量操作对请求json字符串的要求这么严格呢?

bulk中的每个操作都可能要转发到不同的node的shard去执行,如果采用比较良好的json数组格式,允许任意的换行,整个可读性非常棒,读起来很爽,es拿到那种标准格式的json串以后,要按照下述流程去进行处理:

  • 将json数组解析为JSONArray对象,整个数据在内存中出现两份,一份数据是json文本,一份数据是JSONArray对象
  • 解析json数组里的每个json,对每个请求中的document进行路由
  • 为路由到同一个shard上的多个请求,创建一个请求数组
  • 将这个请求数组序列化
  • 将序列化后的请求数组发送到对应的节点上去

这样就耗费更多内存,造成更多的jvm gc开销,导致性能下降,而使用这种严格的json格式之后:

  • 不用解析json字符串,不用将其转换为json对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割json
  • 对每两个一组的json,读取其请求信息,进行document路由
  • 直接将json发送到对应的node上去

这样,减少了内存开销,减少了解析成本,提高了性能

相关文章

  • 016.Elasticsearch文档管理操作

    1.1 创建测试用index 1.2 自动创建索引 当向一个不存在的index中添加document时,可以自动创...

  • 如何有效管理文档(笔记整理)

    文档管理是我们工作中经常用到的,下面就来介绍文档管理的基础原理、实用工具和具体操作。 一、文档管理的基础操作 不要...

  • MongoDB入门手册

    安装 使用 服务管理 管数据库 集合管理 文档管理 条件操作 索引管理 聚合管理 副集管理 分片管理 备份管理 监...

  • mui底部选项卡

    Webview模块管理应用窗口界面,实现多窗口的逻辑控制管理操作:webview API文档 创建webview ...

  • Linux 基础篇-目录

    基本操作 用户和组 [磁盘管理] Linux lVM 逻辑卷 文件和目录 权限 软件包管理 文档打包压缩 进程管理...

  • 使用TortoiseGit管理word文档

    为什么使用TortoiseGit进行团队协作管理word文档?很简单,因为他支持word文档的比较和合并操作啊!让...

  • ES7.9基本操作

    /** 索引操作 @throws IOException */ /*** *文档操作 */ //添加文档 //获取...

  • 合驰产品功能介绍

    目录: 一 OA办公 公告 合同管理 文档中心 工作日志 审批 操作日志 其他申请 二 CRM客户管理 销售机器人...

  • IPO图初相识

    项目逐渐进入收尾阶段,一堆堆验收的文档也接踵而来。前面已经完成了用户操作手册、管理员操作手册、数据库设计文档......

  • 文档操作

    1.设置内容 $(selector).html(content); 例子: $(document).ready(f...

网友评论

      本文标题:016.Elasticsearch文档管理操作

      本文链接:https://www.haomeiwen.com/subject/lxyxqktx.html