Elasticsearch 7 添加和更新文档

Elasticsearch 7 : 添加和更新文档

目录:
使用 POST
添加数据示例1:
添加数据示例2:
一个错误的更新数据方式
使用 _update 更新文档
使用 _update_by_query 更新文档

在 ES 7 中新增索引:
PUT student
{
  "mappings" : {
    "properties" : {
      "name" : {
        "type" : "keyword"
      },
      "age" : {
        "type" : "integer"
      }
    }
  },
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    }
  }
}

使用 POST
POST 用于更新数据,如果不存在,则会创建。
添加数据示例1:
# 请求
POST student/_doc
{
  "name": "张三"
}
# 响应
{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "gCJ8Tm4Buf-uwlbZzC7C",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

添加数据示例2:
指定 _id 为 2。

请求

POST student/_doc/2
{
  "name": "李四"
}

响应

{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

一个错误的更新数据方式

请求

GET student/_doc/2

响应

{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "李四"
  }
}
可以看到没有 age 字段。
更新 age:
# 请求
POST student/_doc/2
{
  "age": 10
}

响应

{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

再次请求数据:
GET student/_doc/2

# {
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 2,
  "_seq_no" : 2,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "age" : 10
  }
}

结果是 version 从1变成了2,而 name 字段不见了。
原因是 POST student/_doc/2 这种语法的效果是覆盖数据。可以理解为先把原文档删除,再索引新文档。
POST student/_doc/2 的效果相同。
使用 _update 更新文档
如何在 name 不消失的情况下更新 age 呢?用 _update。
示例:

# 请求1
POST student/_doc/2
{
  "name": "李四"
}

# 请求2: 新增 age
POST student/_doc/2/_update
{
  "doc": {
    "age": 10
  }
}

# 查询
GET student/_doc/2

# 查询结果
{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 6,
  "_seq_no" : 6,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "李四",
    "age" : 10
  }
}

POST student/_doc/2/_update 这种方式会报错:
#! Deprecation: [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.

所以,建议用下面的方法:
POST student/_update/2
{
  "doc": {
    "age": 11
  }
}

使用 _update 时,ES 做了下面几件事:
从旧文档构建 JSON
更改该 JSON
删除旧文档
索引一个新文档
使用 _update_by_query 更新文档

POST student/_update_by_query
{
  "query": { 
    "match": {
      "_id": 2
    }
  },
  "script": {
    "source": "ctx._source.age = 12"
  }
}

用下面的方法也行,但会有告警:
POST student/_update_by_query
{
  "query": { 
    "match": {
      "_id": 2
    }
  },
  "script": {
    "inline": "ctx._source.age = 12"
  }
}

执行时告警信息如下:
#! Deprecation: Deprecated field [inline] used, expected [source] instead

也就 inline 已经被废弃了,应该使用 source。 所以,最正确的方式是:
POST student/_update_by_query
{
  "query": { 
    "match": {
      "_id": 2
    }
  },
  "script": {
    "source": "ctx._source.age = 12"
  }
}

你可能感兴趣的:(知识总结,技术使用总结,elasticsearch,数据库)