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:truescript.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"]}


出处http://www.cnblogs.com/ljhdo/p/4885796.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容