概要 本篇主要介绍一下document的知识,对document的元数据和基本的语法进行讲解。 document核心元数据 前面入门实战一节有简单介绍过document数据示例,这次我们来详细了解一下它的核心元数据,查询响应报文如下: { "_index": "music", "_type": "children", "_id": "1", "_version": 1, "found": true, "_source": { "name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "75" } } _index元数据 代表一个document存放在哪个index中,项目约定结构类似的数据放在一个索引,不同数据放不同索引里,所以同一个index中document结构基本是类似的,个别document多一个或少一个field,这样Elasticsearch对磁盘存储的利用率最高。 每个index有自己独立的shard存储文件,与其他index互不影响。 命名规范:名称小写,不能以'_', '-', 或 '+'开头。 _type元数据 ES 6.0.0之后一个index下面只能有一个type,最早指定是啥就是啥。 命名规范:可以用'_'开头,由于只有一个,官方示例上直接使用'_doc'。 _id元数据 document的唯一标识,与index一起唯一标识和定位一个document,可以手动指定,也可以由ES自动创建。 _version元数据 ES内部使用乐观锁对document的写操作进行控制,version版本号最初是1,更新操作成功后自动+1。 found元数据 document的搜索标志,成功是true,未搜索到是false。 _source元数据 里面是我们在新增时放在http request body的json串内容,是保存的业务数据,默认Get操作时,会原封不动地全部返回给客户端。 用Get命令搜索document时,可以定制返回的结果,在请求的_source中指定想要的field即可,示例命令: GET /music/children/_search { "query": { "match_all" : {} }, "_source": ["name","content"] } document id document的id手动指定与自动生成两种方式: 手动指定 PUT命令行指定ID时,即手动方式 PUT /music/children/id 自动生成 PUT命令行没指定ID时,此时ES会自动生成的id,长度为20个字符,URI安全,base64编码,GUID,保证不重复。 PUT /music/children 我们的项目中怎么选择ID生成方式呢? 一般来说,看Elasticsearch在系统里承担的角色,如果是业务系统,本身有关系型数据完成数据的落地,Elasticsearch的价值就是填补关系型数据的全文搜索的短板,Elasticsearch的数据源头,本身在带ID的,这种情况下应该使用手动指定ID的方式,直接用数据库存储数据的ID即可,后续的搜索功能,也很容易与数据库建立对应 关系。例如订单数据,此时的ID直接使用订单ID即可,而订单ID的生成方式,无论是自增ID,雪花ID,对Elasticsearch来讲都不要紧,保证唯一性即可。 而自动ID生成的场景,比如有些系统,它没有关系型数据库,Elasticsearch可能就是它唯一的数据落地方案,这种数据结构,ID没有太多的重要性,这时让Elasticsearch自动生成一个,可以保存到Elasticsearch即可。 tips: GUID、UUID、COMB概念 UUID:是128位整数(16字节)的通用唯一识别码 (Universally Unique Identifier),它是由开放软件基金会(OSF)定义的一个软件建构的标准。 GUID:是微软对UUID这个标准的实现。UUID还有其它各种实现,不止GUID一种。 COMB(combine)型是数据库特有的一种设计思想,可以理解为一种改进的GUID,它通过组合GUID和系统时间,以使其在索引和检索时有更优的性能。 GUID与UUID的区别,生成的格式不同。 document写操作 强制创建 强制创建在语法上多了_create参数,或op_type=create,如 PUT /music/children/id/_create 或 PUT /music/children/id?op_type=create 强制创建与全量替换的异同点: 当ID不存在时,二者的效果一样。 当ID存在时,全量替换做更新操作,强制创建报错,提示"version conflict, document already exists"错误。 删除document 如果对一个document执行delete操作,ES不会立即进行物理删除,而是先标记为deleted状态,当文件数据变多满足一定条件后,ES再执行物理删除,类似于JVM的垃圾清理。 这个过程叫软删除,也叫lazy delete。 全量替换&增量更新 全量替换 全量替换命令可以多次执行,如果ID不存在,执行创建document操作,如果ID存在,执行更新,语法示例: PUT /music/children/id 全量替换的原理:当全量替换请求发送到ES上时,会将该ID原有的document执行软删除,然后再新建一个document,把request body的内容存储到新的document中,后续的GET查询只关注非deleted状态的document,这样就完成了一次全量替换操作。 增量更新前必须保证该ID是存在的,存在执行更新操作,若不存在,抛出"document_missing_exception"错误信息。 增量更新 增量更新的原理,与全量替换基本一致,也有软删除过程,只是创建新的document时,需要将原有的document数据拷贝一份,再用增量的内容进行覆盖,得到一个新的document。 增量更新比全量替换的优点 查询修改写回操作,都发生在一个shard内部,网络带宽更小(有2次网络传输),大大提升了性能 减少了查询和修改中的时间时隔,可以有效减少并发冲突的情况(毫秒级的更新) 减轻应用程序拼接全量数据的工作量(如果json field比较多,拼接一个完整的document是很费事的) 小结 本篇主要围绕document的元数据进行了简单的讲解,希望可以加深对document的印象。 专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区https://www.cnblogs.com/huangying2124/p/11955515.html