在ES中对索引文档进行更新

作者: 饿虎嗷呜 | 来源:发表于2020-04-11 01:24 被阅读0次

简介

ElasticSearch的文档写入是以不可修改的形式写入的,一条文档记录一旦被写入其本身就不能被修改了。然而,现实中存在修改这些数据的需求,那怎么办呢?当上帝给你关上一扇门的时候,他一定给你留了一个窗口。虽然我们不能直接修改这个文档本身,但是我们可以通过更新一条_id一样的文档,并更新版本号的方式来修改这条记录。我们可以通过三种姿势进行更新。

姿势1,直接index

PUT test1/_doc/1
{
  "name": "bbbb"
}
# Do query
PUT test1/_doc/1
{
  "name": "bbbb",
  "age": 33
}
# Do query
PUT test1/_doc/1
{
  "name": "bbbb"
}
# Do query


按顺序执行上面的三条put操作,然后查询,我们可以看到相应的查询结果是:

  "_version": 1
  "_source" : {
    "name" : "bbbb"
  }
  =========================
  "_version": 2
  "_source" : {
    "name" : "bbbb",
    "age" : 33
  }
  =========================
  "_version": 3
  "_source" : {
    "name" : "bbbb"
  }
  

可以看到每次put之后,版本号都会递增1位,同时后面的数据会覆盖之前的数据。

如果我并不想每次都通过这样把全部文档内容再输入一次的形式来,而是希望基于前一个版本的文档进行增减或者修改,那又应该怎么做呢。ES为我们提供了update API。

姿势2,使用update API

ES 提供了update API,使我们可以针对某个id的文档,进行局部更新。我们可以使用painless脚本或者直接在update中设置doc字段的参数的形式进行。

考虑以下文档。

PUT test14/_doc/1
{
  "name": "aaaa",
  "age": 15,
  "sex": "male"
}

如果我想修改年龄的话,可以有两种方法来进行:

POST test14/_update/1
{
  "doc": {
    "age": 14
  }
}

POST test14/_update/1
{
  "script": {
    "lang": "painless",
    "source": """
      ctx._source.age = 14
    """
  }
}

两种方法都可以将age修改为14。

如果我们想增加一个属性”weight“该怎么做呢?

POST test14/_update/1
{
  "doc": {
    "weight": 90
  }
}

POST test14/_update/1
{
  "script": {
    "lang": "painless",
    "source": """
      ctx._source.weight = 90
    """
  }
}

如果我们想移除”sex“字段,这种情况下,只能用painless脚本了。

POST test14/_update/1
{
  "script": {
    "lang": "painless",
    "source": """
      ctx._source.remove("sex");
    """
  }
}

这三种情况是最基本的,还有一些其他用法,可以参考update的官方文档。

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/docs-update.html

需要注意,使用update api只能使用ES索引的内置版本号,如果强行指定版本号,update操作会发生错误。

上面两种方法需要指定文档id,ES还提供了基于search的update API,及update_by_query API。

姿势3,使用update_by_query API

update_by_query API的第一种使用方式是什么都不指定,直接使用。

POST twitter/_update_by_query?conflicts=proceed

我一开始看到这种用法,觉得特别疑惑,因为这样做除了更新了版本号,似乎也没有什么变化。后来读了官方文档才了解到这种用法的含义。

在设置索引配置的时候,有一个dynamic属性,如果设置成false的话,如果碰到没有事先映射过的字段,是不会做索引,搜索不到的。需要注意,是搜索不到,但不是没有存储,这个数据还是在的。那怎样能使得这个数据能够被索引到呢,这个时候update_by_query就能排上用场了。我们先更新这个索引的mapping,然后调用update_by_query API。对应的文档会重新索引一次,之前不能搜索的字段就变得能够被搜索到了。

和query API一样,update_by_query也可以拥有一个query块,作为update的条件出现:

POST twitter/_update_by_query
{
  "script": {
    "source": "ctx._source.likes++",
    "lang": "painless"
  },
  "query": {
    "term": {
      "user": "kimchy"
    }
  }
}

同样也可以使用painless进行update操作。

PUT _ingest/pipeline/set-foo
{
  "description" : "sets foo",
  "processors" : [ {
      "set" : {
        "field": "foo",
        "value": "bar"
      }
  } ]
}
POST twitter/_update_by_query?pipeline=set-foo

在进行update_by_query的时候,还可以指定pipeline,使用pipeline的处理器处理文档。

还有一些其他用法,可以参考官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/docs-update-by-query.html

相关文章

  • 在ES中对索引文档进行更新

    简介 ElasticSearch的文档写入是以不可修改的形式写入的,一条文档记录一旦被写入其本身就不能被修改了。然...

  • ElasticSearch文档操作

    本节我们来讲解一下ES中文档的相关操作 一:索引/更新文档 ES中索引和更新文档都是PUT操作。 比如我又一条测试...

  • Elasticsearch中的_source、_all、stor

    原始文档数据在进入es中之后,es会将其存为两份,一部分是对其中的索引字段数据进行分词索引,然后存储所有的分词索引...

  • ElasticSearch04批量操作

    读取多份文档 显式声明索引名称和文档类型 在body中声明索引名称和文档类型 写入多分文档 es.bulk hel...

  • 信息检索复习(2)——词项词典及倒排记录表

    构建倒排索引步骤 收集待建索引的文档(Document) 对这些文档中的文本进行词条化(Tokenizer) 对第...

  • Elasticsearch 使用 RESTful API 操作文

    之前我们学习了索引相关的操作,有了索引,我们就可以往索引中添加文档,完成各种文档的操作,操作文档是 ES 中相对复...

  • 词项词典与倒排记录表

    构建倒排索引的几个主要步骤: 1 收集待建索引的文档2 对这些文档中的文本进行词条化3 对步骤2中的词条进行语言学...

  • python对es基础的增删改查

    安装API python对索引进行操作 建立es连接 创建索引 删除索引 判断索引存在 对索引加入mapping ...

  • Data

    在ES中,每个字段的所有数据都是默认被索引的。 什么是文档(document) 文档类似于对象,是指最顶层或者根对...

  • ELK 聚合查询

    在elasticsearch中es支持对存储文档进行复杂的统计.简称聚合。 ES中的聚合被分为两大类。 1、Met...

网友评论

    本文标题:在ES中对索引文档进行更新

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