ElasticSearch查询 第二篇:文档更新
《ElasticSearch查询》目录导航:
- ElasticSearch查询 第一篇:搜索API
- ElasticSearch查询 第二篇:文档更新
- ElasticSearch查询 第三篇:词条查询
- ElasticSearch查询 第四篇:匹配查询(Match)
- ElasticSearch查询 第五篇:布尔查询
ElasticSearch是性能优化的分布式全文搜索引擎,存储数据的载体是文档(Document),它的优势在于搜索速度快和支持聚合操作,在更新文档时,基本上能够达到实时搜索。ElasticSearch引擎总是按照文档标识来更新数据,并发控制是通过顺序的版本ID(version)实现的,控制写-写、写-读冲突,实现数据弱一致性。
在ElasticSearch引擎中,索引定义了文档的逻辑存储,索引是由段(Segment)组成的,段不是实时更新的,这意味着,在建立索引时,一个段写入磁盘后,就不再被更新。被删除文档的信息存储在一个单独的文件中,在搜索数据时,ElasticSearch首先从段中查询,再从查询结果中过滤被删除的文档,这意味着,段中存储”未被删除文档“的密度降低。多个段可以通过段合并(Segment Merge)操作把“已删除”的文档将从段中物理删除,将未删除的文档合并成一个新段,新段中没有”已删除文档“,因此,段合并操作能够提高索引的查找速度,但段合并是IO密集型的,需要消耗大量的IO操作。
一旦数据存储在倒排索引中,就不能被修改,因此,更新文档是一项复杂的任务。在内部,ElasticSearch引擎必须首先获取文档(从_source属性中获得数据),删除旧的文档,更新_source属性,然后重新索引该文档,使之可被搜索到,就是说,文档更新的流程,实际上是先标记文档被删除,后插入新的文档,最后将新文档编入索引。
数据的更新,主要是通过_update端点,编写内嵌脚本(inline script)来实现。默认的脚本语言是Groovy,Groovy是内置的脚本语言,不需要安装,默认是禁用的,在未启用动态脚本的结点上执行脚本更新,ElasticSearch引擎将会抛出异常消息:
scripts of type [inline], operation [update] and lang [groovy] are disabled
要启用脚本更新,必须修改每个节点(node)的全局配置文件 config/elasticsearch.yml,添加配置选项:
script.inline: true script.indexed: true
一,编入索引(Index Data)
索引API用于将一个类型化的JSON结构添加到一个索引中,或者更新索引中的一个文档,使之能够被搜索到。
1,使用文档标识编入索引
在把文档编入索引时,如果在API中显式提供文档的标识(_id),那么ElasticSearch引擎使用Upsert(更新或增加)方式更新索引,这意味着,如果索引中已经存在相同ID的文档,那么ElasticSearch更新该文档(实际上是先删除,后添加);如果索引中不存在相同ID的文档,那么把文档添加索引中。
PUT host:port/twitter/tweet/1 -d { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
2,指定操作类型
在编入索引时,索引操作支持参数op_type,用于指定索引数据的操作类型是create,当文档ID不存在时,将文档添加到索引中;当显式指定操作类型是create时,如果创建的文档ID已经存在于索引中,那么创建操作将失败。
PUT 'http://localhost:9200/twitter/tweet/1?op_type=create' -d PUT 'http://localhost:9200/twitter/tweet/1/_create' -d
3,自动生成文档标识
在索引文档时,如果没有指定文档标识,那么ElasticSearch将会自动生成文档标识,并自动把操作类型(op_type)设置为create,注意,自动生成文档标识是更新操作,修改索引中的文档,而不是新建一个新的文档,因此使用POST动词,而不是PUT动词。
POST 'http://localhost:9200/twitter/tweet/' -d '{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }'
二,删除文档
在ElasticSearch引擎中删除文档非常简单,通过文档标识删除文档,实际上,该文档并没有从索引中物理删除,只是在其他文件中被标记删除,只要ElasticSerach 引擎执行段合并操作时,才会真正从物理上删除文档。
DELETE 'http://localhost:9200/twitter/tweet/1'
三,在更新端点(_update)更新文档
ElasticSearch引擎在更新端点(_update)上更新文档,更新操作首先从索引中查询到文档,执行更新逻辑,并将更新之后的文档重新索引,使之能够被搜索到。在更新文档时,ElasticSearch使用版本控制并发操作可能产生的冲突。更新端点(_update)主要是基于脚本的文档更新,ElasticSearch引擎从索引中获取文档,使用脚本和可选的参数执行更新操作,并将文档重新编入索引。在更新时,即使只修改文档的部分字段,ElasticSearch也会重新索引整个文档,并使用文档版本避免读-写冲突。使用端点(_update)和内嵌脚本对文档执行更新操作,必须启用_source 字段。
1,根据参数值,更新指定文档的字段
ctx 是单词context的缩写,表示文档的上下文,在script节中,使用ctx引用文档。
POST 'localhost:9200/test/type1/1/_update' -d '{ "script" : { "inline": "ctx._source.counter += count", "params" : { "count" : 4 } }, "upsert" : { "counter" : 1 } }'
示例,脚本更新文档的字段counter,把ID为1的文档的counter字段增加4。当文档中没有该字段时,例如,想要增加文档中的counter字段值,而该字段不存在,在请求中使用upsert字段,提供counter字段的默认值。
upsert参数,当指定的文档不存在时,upsert参数包含的内容将会被插入到索引中,作为一个新文档;如果指定的文档存在,ElasticSearch引擎将会执行指定的更新逻辑。
例如以下脚本,当文档存在时,把文档的counter字段设置为1;当文档不存在时,插入一个新的文档,文档的counter字段的值是2。
{ "script":{ "inline":"ctx._source.counter= 1" }, "upsert":{"counter":2} }
2,向_source字段,增加一个字段
POST 'localhost:9200/test/type1/1/_update' -d '{ "script" : "ctx._source.name_of_new_field = \"value_of_new_field\"" }'
3,从_source字段中,删除一个字段
POST 'localhost:9200/test/type1/1/_update' -d '{ "script" : "ctx._source.remove(\"name_of_field\")" }'
4,根据提供的文档片段更新数据
使用"doc"字段传递文档片段(Partial Document),doc字段包含完整文档的一部分字段,ElasticSearch引擎对已经存在的文档进行归并(Merge)更新,这就意味着,如果文档中存在doc节指定的字段,那么替换文档中的字段值;如果文档中部存在doc节指定的字段,那么向文档中增加新的字段,例如,对文档标识为1的文档,将该文档中的name字段更新为“new_name”:
POST 'localhost:9200/test/type1/1/_update' -d '{ "doc" : { "name" : "new_name" }, "detect_noop": false }'
detect_noop参数,在更新部分文档时,文档值被归并到_source字段,默认值是true,这意味着,当ElasticSearch引擎会检测_source字段的数据发生变化时,ElasticSearch引擎将重新索引该文档;如果设置设置为False时,ElasticSearch引擎不管_source字段的数据是否变化,都会更新文档。
5,更新操作的参数
retry_on_conflict参数:指定更新操作在发生版本冲突时重试的次数。
对于文档的更新操作,ElasticSearch引擎需要顺序执行三个阶段:获取文档(Get),更新文档(Update)和索引文档(Index)。在更新文档时,其他进程可能已经把相同的文档修改了。在默认情况下,更新操作由于检测到版本冲突而就立即失败,抛出异常。参数retry_on_conflict控制在ElasticSearch引擎真正抛出异常之前,更新操作重新执行的次数。
fields 参数:从已更新的文档中,返回有关字段(Relevant Fields)的数据,如果将fields设置为_source,将返回整个文档的所有数据。
{ "doc":{ "counter":3 }, "upsert":{"counter":2}, "fields":["counter"], "detect_noop":true }
四,批量操作(_bulk)
批量端点(_bulk)用于在一个请求(Request)中封装多个操作,请求格式是/index_name/type_name/_bulk。在请求主体中,包含多个操作请求,单个请求的格式相同,不同之处在于,每个请求包含两行JSON对象:信息行和数据行,由于批量端点必须识别换行,因此,发送的请求格式 使用--data-binary 代替 -d:
POST /_bulk?pretty --data-binary request_body
请求主动体,有四种类型,分别是index、update、create和delete,实现数据的索引分析,文档更新,文档创建和文档删除。
1,在索引中增加或替换现有文档,使用index节
{"index":{"_index":"index_name","_type":"type_name","_id":####}} {"doc_field1":"xx","doc_field2":"yy"}
2,从索引中移除文档,使用delete节
{"delete":{"_index":"index_name","_type":"type_name","_id":####}}
3,当索引中不存在文档定义时,在索引中增加新文档,使用create节
{"create":{"_index":"index_name","_type":"type_name","_id":####}} {"doc_field1":"xx","doc_field2":"yy"}
4,当更新文档时,使用update节
{ "update" : {"_id" : "1", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} } { "doc" : {"field" : "value"} } { "update" : { "_id" : "0", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} } { "script" : { "inline": "ctx._source.counter += param1", "params" : {"param1" : 1}}, "upsert" : {"counter" : 1}} { "update" : {"_id" : "2", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} } { "doc" : {"field" : "value"}, "upsert" : true } { "update" : {"_id" : "3", "_type" : "type1", "_index" : "index1", "fields" : ["_source"]} } { "doc" : {"field" : "value"} } { "update" : {"_id" : "4", "_type" : "type1", "_index" : "index1"} } { "doc" : {"field" : "value"}, "fields": ["_source"]}
参考文档:
Elasticsearch Reference [2.4] » Document APIs
Elasticsearch Reference [2.4] » Document APIs » Bulk API
Elasticsearch Reference [2.4] » Document APIs » Update API
Elasticsearch Reference [2.4] » Modules » Scripting
本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/4885796.html,如需转载请自行联系原作者

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
大数据的实时处理STORM简介
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/9292831 《大数据的实时处理STORM简介》 作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs 新技术如社交媒体、电邮、博客、地理信息系统GIS、无线射频识别RFID和智能手机等为基于服务信息构建提供了新的机会。 处理大数据常见的方法和框架是Apache Hadoop,它以批处理的方式运行数据处理任务。现在,如果需要实时处理数据和实时显示数据,那这种基于批处理的方式并不是很适合。 STORM是一个开源框架,来自Twitter公司,其目标是大数据流的实时处理。STORM可以可靠地处理无限的数据流,实时处理Hadoop的批任务。STORM非常简单,支持所有的编程语言,使用它充满了乐趣。 STORM有很多适用场景:实时分析、在线机器学习、连续计算、分布式RPC、分布式ETL、易扩展、支持容错,可确保你的数据得到处理,易于构建和操控。 STORM的地址见:http://storm-projec...
- 下一篇
大数据应用之双色球算奖平台总体设计历史数据存储篇
大数据应用之双色球算奖平台总体设计历史数据存储篇 作者:张子良 版权所有,转载请注明出处 1.1 引子:文件OR数据库 历史期次的双色球选注数据的存储,采用什么样的格式比较好呢?这需要重点从三个方面考虑,一、文件访问方便吗?二、文件服务器空间够用吗?三、软硬件故障环境下,如何保障数据的可用性。基于这几个方面的考虑,到底是采用文件存储还是采用数据库存储呢?本文,从传统和前沿技术两个角度给出了两种相应的解决方案。 1.2 文件存储 1.2.1 三大问题 根据上一篇《大数据应用之双色球算奖平台总体设计数据规模估算篇》分析,双色球单期次数据的存储规模在7G左右,记录数在2亿条左右。可以考虑以文本文件的方式进行存储,这里面面临三大问题,一、单个文件过大的问题,访问不便,文本文件一般来讲超过200M,使用常规文本文件阅读器打开,都会成为问题,各位可以自行尝试。二、历史期次存储空间问题,技术总是在发展的,目前一般的服务器存储空间,单台服务器硬盘配置个NT,从技术和成本角度,都不会成为障碍,双色球每周三期,考虑到节假日的因素,每年约156期,156*7=1092,所需空间约1T。三、数据高可用性问题,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题