elasticsearch 修改的底层逻辑
elasticsearch 修改在内部,修改标记旧文档为删除(增加了一个 version 版本号)并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。
elasticsearch 会在你继续索引更多数据时清理被删除的文档,或者进行强制清除命令把这种过期的旧数据删除掉。因为这种过期旧数据太多在一定程度上将会影响查询效率。
有时候我们修改的内容非常多,达到索引的 80% 上时,会考虑索引重建即 reindex,索引重建有点相当于删除表重新添加数据的感觉。
elasticsearch 修改单条数据
下面通过代码的方式演示修改单条数据的方式,并且结合 head 查看修改后的 version。
查看修改前的数据
1.确定 es 服务启动。
2.打开浏览器访问http://127.0.0.1:9200/_plugin/head,查看我们前面创建的 userInfo。
选中数据,查看 version 信息。
image.png
在com.syl.es下新建 UpdateData 类
编写更新单条数据的函数
package com.syl.es;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
public class UpdateData {
/**
* @param args
*/
public static void main(String[] args) {
updateEs();
}
/**
* 更新索引
*/
public static void updateEs(){
//索引服务的地址
String elasticServer= "127.0.0.1";
//索引服务的端口
Integer elasticServerPort = 9300;
Client client=null;
try{
//初始化连接
Settings settings = Settings.settingsBuilder().build();
client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName(elasticServer), elasticServerPort));
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//设置更新的字段
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("name","王美丽")
.field("nickname","美丽")
.field("birthdate",df.format(new Date()))
.endObject();
//更新为1的字段数据
UpdateResponse response=client.prepareUpdate("user","userInfo","1")
.setDoc(jsonBuilder)
.get();
String _index = response.getIndex();
String _type = response.getType();
String _id = response.getId();
long _version = response.getVersion();
boolean created = response.isCreated();
System.out.println(_index+" "+_type+" "+_id+" "+_version+" "+created);
//关闭连接
client.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
以 Java Application 的方式,运行UpdateData.java文件。
查看 version 变化
打开 head 查看 version 变化 点击 id 为 1 的数据查看 version
image.png
根据结果我们可以看见 version 已经为 2,并且数据已经按照我们编写的修改了。
elasticsearch 修改多条数据
下面通过代码的方式演示修改多条数据的方式,并且结合 head 查看修改后的 version。
编写批量修改多条数据的方法 batchUpdateEs
在UpdateData.java,添加 batchUpdateEs 函数。
/**
* 批量更新索引数据
*/
public static void batchUpdateEs(){
String elasticServer= "127.0.0.1";
Integer elasticServerPort = 9300;
Client client=null;
try{
Settings settings = Settings.settingsBuilder().build();
client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName(elasticServer), elasticServerPort));
//初始化数据
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
List dataList = new ArrayList();
Map dataMap1=new HashMap();
dataMap1.put("name","张中国");
dataMap1.put("nickname", "张中");
dataMap1.put("nativeplace", "上海静安寺");
dataMap1.put("address", "上海静安寺1街坊10栋");
dataMap1.put("birthdate", "1980-02-15");
dataMap1.put("id", "2");
Map dataMap2=new HashMap();
dataMap2.put("name","张三丰");
dataMap2.put("nickname", "张三");
dataMap2.put("nativeplace", "上海静安寺");
dataMap2.put("address", "上海静安寺1街坊10栋");
dataMap2.put("birthdate", "2018-01-23");
dataMap2.put("id", "3");
dataList.add(dataMap1);
dataList.add(dataMap2);
BulkRequestBuilder bulkRequest = client.prepareBulk();
int y=dataList.size();
//执行批量更新
for(int i=0;i<y;i++){
Map<String, Object> m =(Map<String, Object>) dataList.get(i);
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("name",m.get("name").toString())
.field("nickname",m.get("nickname").toString())
.field("nativeplace",m.get("nativeplace").toString())
.field("address",m.get("address").toString())
.field("birthdate",m.get("birthdate").toString())
.endObject();
bulkRequest.add(client.prepareUpdate("user", "userInfo",m.get("id").toString())
.setDoc(jsonBuilder));
if (i % 10000 == 0) {
bulkRequest.execute().actionGet();
}
}
bulkRequest.execute().actionGet();
//关闭连接
client.close();
}catch (Exception e) {
e.printStackTrace();
}
}
修改主函数,调用删除索引函数
注释掉 updateEs 的调用,增加调用 batchUpdateEs。
public static void main(String[] args) {
//更新索引数据
//updateEs();
//批量更新数据
batchUpdateEs();
}
运行代码
以 Java Application 的方式,运行UpdateData.java文件。
查看执行结果
打开 head 查看 version 及数据变化(实际项目我们一般不会关注 version,这里只是让大家知道它底层每更新一次 version 都在变化)
大家可以看到数据跟 version 都已经变了。
网友评论