栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Elasticsearch更新文档

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Elasticsearch更新文档

Elasticsearch系列文档

这个系列的文章会基于Java描述Elasticsearch中主要API的用法,其中会加入一些自己的理解,如有错误之处还请不宁赐教,非常感谢。已经发布的文章在笔者有所感悟后还会不断更新,以期记录自己学习Elasticsearch的过程。


Elasticsearch更新文档
  • Elasticsearch系列文档
  • 前言
  • 1 通过文档id更新文档
    • 1.1 创建请求
    • 1.2 构建更新内容
    • 1.3 可选参数
      • 1.3.1 冲突重试次数
      • 1.3.2 允许返回文档
      • 1.3.3 脚本upsert
      • 1.3.4 更新视为upsert
    • 1.4 执行请求
    • 1.5 请求响应
  • 2 通过查询条件更新文档
    • 2.1 创建请求
    • 2.2 可选参数
      • 2.2.1 冲突策略


前言

JavaAPI下的Elasticsearch用法。

1 通过文档id更新文档 1.1 创建请求
UpdateRequest request = new UpdateRequest(
        "posts", 
        "1"); 
1.2 构建更新内容

可以使用内联脚本更新部分文档。如下将字段field 的值加上4。生产环境不推荐使用脚本,不方便排错和维护,并且影响操作性能。

Map parameters = singletonMap("count", 4); 

Script inline = new Script(ScriptType.INLINE, "painless",
        "ctx._source.field += params.count", parameters);  
request.script(inline);  

也可以使用一般方法更新部分文档。如下分别使用json、Map、XContentBuilder 和键值对构建更新内容。如果要更新的文档存在,这部分文档会被合并进去。

UpdateRequest request = new UpdateRequest("posts", "1");
String jsonString = "{" +
        ""updated":"2017-01-01"," +
        ""reason":"daily update"" +
        "}";
request.doc(jsonString, XContentType.JSON);
Map jsonMap = new HashMap<>();
jsonMap.put("updated", new Date());
jsonMap.put("reason", "daily update");
UpdateRequest request = new UpdateRequest("posts", "1")
        .doc(jsonMap); 
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
    builder.timeField("updated", new Date());
    builder.field("reason", "daily update");
}
builder.endObject();
UpdateRequest request = new UpdateRequest("posts", "1")
        .doc(builder);  
UpdateRequest request = new UpdateRequest("posts", "1")
        .doc("updated", new Date(),
             "reason", "daily update");

如果要更新的文档不存在,可以添加一些内容来创建新文档,这个操作叫upsert。如下,要更新的文档不存在,则创建一个新文档并插入jsonString 中的内容。

String jsonString = "{"created":"2017-01-01"}";
request.upsert(jsonString, XContentType.JSON);
1.3 可选参数 1.3.1 冲突重试次数

如果在写入更新内容之前文档被改动了,更新操作会重试多少次。默认为0,即出现冲突不会重试。

request.retryOnConflict(3); 
1.3.2 允许返回文档

更新操作会返回受影响的文档,默认为false,即不返回。

request.fetchSource(true);

这个选项也可以返回或排除指定字段

String[] includes = new String[]{"updated", "r*"};
String[] excludes = Strings.EMPTY_ARRAY;
request.fetchSource(
        new FetchSourceContext(true, includes, excludes));
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"updated"};
request.fetchSource(
        new FetchSourceContext(true, includes, excludes)); 
1.3.3 脚本upsert

无论要更新的文档不存在,脚本依然会执行并且会创建出新文档。

request.scriptedUpsert(true);
1.3.4 更新视为upsert

更新部分文档时,如果要更新的文档不存在,则视为使用upsert方法,即不存在则创建新的文档。

request.docAsUpsert(true);
1.4 执行请求
UpdateResponse updateResponse = client.update(
        request, RequestOptions.DEFAULT);
1.5 请求响应

updateResponse.getResult()可以返回文档是被创建、更新、删除还是这次更新没有改变任何文档,即你的更新内容和原内容本来就是一致的。

String index = updateResponse.getIndex();
String id = updateResponse.getId();
long version = updateResponse.getVersion();
if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
    
} else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
    
} else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
    
} else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
    
}

如果设置了request.fetchSource(true),还可以获取到被更新的文档。result.isExists()在默认情况下是false,因为这时有request.fetchSource(false)。

GetResult result = updateResponse.getGetResult(); 
if (result.isExists()) {
    String sourceAsString = result.sourceAsString(); 
    Map sourceAsMap = result.sourceAsMap(); 
    byte[] sourceAsBytes = result.source(); 
} else {
    
}

如果要更新的文档不存在,则可以用try catch捕获这个异常。

UpdateRequest request = new UpdateRequest("posts", "does_not_exist")
        .doc("field", "value");
try {
    UpdateResponse updateResponse = client.update(
            request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
    if (e.status() == RestStatus.NOT_FOUND) {
        
    }
}
2 通过查询条件更新文档 2.1 创建请求

同样可以一次更新多个index

UpdateByQueryRequest request =
        new UpdateByQueryRequest("source1", "source2");

当您通过查询请求提交更新时,Elasticsearch 会先生成索引的快照,并使用内部版本号进行匹配。 当版本匹配时,更新文档并增加版本号。 如果在生成快照和处理更新操作之间文档发生更改,则会导致版本冲突并且操作失败。 你可以通过设置request.setConflicts(“proceed”)来计算版本冲突,从而避免操作停止和返回。 请注意,如果您选择计算版本冲突,则该操作可能会尝试从源更新比 max_docs 更多的文档,直到它成功更新了 max_docs 文档,或者它已经遍历了源查询中的每个文档。

2.2 可选参数 2.2.1 冲突策略
request.setConflicts("proceed")

当使用查询请求提交更新时,Elasticsearch 会先生成索引的快照,并使用内部版本号进行匹配。 当版本匹配成功时,Elasticsearch 更新文档并增加版本号。 如果在生成快照和处理更新操作之间文档发生更改,则会导致版本冲突并且操作失败。
这时你可以通过设置request.setConflicts(“proceed”)来计数版本冲突,这样可以避免操作停止并返回。

后面的内容和《Elasticsearch删除文档》那边的差球不多,同样也是使用多重搜索获取到匹配的文档,再使用批量更新写入要更新的内容。后面多余的就不写了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/871335.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号