本文转载自:http://blog.csdn.net/u014039577/article/details/51802078,仅为了个人收藏,请支持原创作者。
Elasticsearch在2.0以前版本,删除操作有两种方式,一种是通过id来进行删除,但是这种方式一般不常用,因为id不容易得到;另一种方式是通过先查询操作,然后删除,也就是通过client.prepareDeleteByQuery这种方式来根据条件批量删除数据:
[java] view plain copy
DeleteByQueryResponse response = client.prepareDeleteByQuery(“library”)
.setQuery(QueryBuilders.termQuery(“title”, “ElasticSearch”))
.execute().actionGet();

但是Delete by Query在2.0版本及其以上的版本已经被移除了,因为这种方式会自动强制刷新,所以在大量索引并发的情况下,会很快造成内存溢出。
详情可查看:https://www.elastic.co/guide/en/elasticsearch/client/java-api/1.7/delete-by-query.html
那么在2.0以后的版本,我们如何来进行批量的删除呢?
我们可以先通过Search API查询,然后得到需要删除的批量数据的id,然后再通过id来删除,但是这种方式在大批量数据的删除的时候,依然是行不通的。
具体实现代码:
[java] view plain copy
public void deleteByTerm(Client client){
BulkRequestBuilder bulkRequest = client.prepareBulk();
SearchResponse response = client.prepareSearch(“megacorp”).setTypes(“employee”)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(QueryBuilders.termQuery(“first_name”, “xiaoming”))
.setFrom(0).setSize(20).setExplain(true).execute().actionGet();
for(SearchHit hit : response.getHits()){
String id = hit.getId();
bulkRequest.add(client.prepareDelete(“megacorp”, “employee”, id).request());
}
BulkResponse bulkResponse = bulkRequest.get();
if (bulkResponse.hasFailures()) {
for(BulkItemResponse item : bulkResponse.getItems()){
System.out.println(item.getFailureMessage());
}
}else {
System.out.println(“delete ok”);
}

}

同样通过delete-by-query插件,我们还可以根据type来批量删除数据,这种方式能够删除大批量的数据,他是现将要删除的数据一个一个做标记,然后再删除,于是效率会比较低。下面是官网的说明:https://www.elastic.co/guide/en/elasticsearch/plugins/2.3/plugins-delete-by-query.html
Queries which match large numbers of documents may run for a long time, as every document has to be deleted individually. Don’t use delete-by-query to clean out all or most documents in an index. Rather create a new index and perhaps reindex the documents you want to keep.
可见这种删除方式并不适合大批量数据的删除,因为效率真的是很低,我是亲身体验过了。

这种方式需要先引入delete-by-query插件包,然后使用插件的api来删除:
[java] view plain copy

org.elasticsearch.plugin
delete-by-query
2.3.2

具体实现代码:
[java] view plain copy
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ResourceBundle;
import java.util.Stack;

import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
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.plugin.deletebyquery.DeleteByQueryPlugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xgd.log.common.ExceptionUtil;

public class EsDeleteByType {

private static final Logger logger = LoggerFactory.getLogger(EsDeleteByType.class);
private Client client;  private static ResourceBundle getEsConfig(){  return ResourceBundle.getBundle("elasticsearch");
}  private void getClient(){  String clusterName = getEsConfig().getString("clusterName");  String hosts = getEsConfig().getString("hosts");  if (hosts == null || clusterName == null) {  throw new IllegalArgumentException("hosts or clusterName was null.");  }  Settings settings = Settings.settingsBuilder().put("cluster.name", clusterName).build();  client = TransportClient.builder()  .addPlugin(DeleteByQueryPlugin.class)  .settings(settings).build();  String[] hostsArray = hosts.split(",");  for(String hostAndPort : hostsArray){  String[] tmpArray = hostAndPort.split(":");  try {  client = ((TransportClient)client).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(tmpArray[0]), Integer.valueOf(tmpArray[1])));  } catch (NumberFormatException e) {  logger.error(ExceptionUtil.getTrace(e));  } catch (UnknownHostException e) {  logger.error(ExceptionUtil.getTrace(e));  }  }
}  /** * 判断一个index中的type是否有数据 * @param index * @param type * @return * @throws Exception */
public Boolean existDocOfType(String index, String type) throws Exception {  SearchRequestBuilder builder = client.prepareSearch(index).setTypes(type)  .setSearchType(SearchType.QUERY_THEN_FETCH)  .setSize(1);  SearchResponse response = builder.execute().actionGet();  long docNum = response.getHits().getTotalHits();  if (docNum == 0) {  return false;  }  return true;
}  /** * 根据type来删除数据 * @param index * @param types * @return */
public long deleteDocByType(String index, String[] types) {  getClient();  long oldTime = System.currentTimeMillis();  StringBuilder b = new StringBuilder();  b.append("{\"query\":{\"match_all\":{}}}");  DeleteByQueryResponse response = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE)  .setIndices(index).setTypes(types)  .setSource(b.toString())  .execute().actionGet();  Stack<String> allTypes = new Stack<String>();  for(String type : types){  allTypes.add(type);  }  while(!allTypes.isEmpty()){  String type = allTypes.pop();  while(true){  try {  if (existDocOfType(index, type) == false) {  break;  }  } catch (Exception e) {  logger.error("queryError: " + e.getMessage());  }  }  }  System.out.println(System.currentTimeMillis() - oldTime);  return response.getTotalDeleted();
}

}

那么当我们在开发中,使用到elasticsearch的时候,总会涉及到大批量数据的删除,我们要怎么办呢?
经过很长时间的纠结,我发现使用elasticsearch存储数据的时候,千万不要把所有数据都存储于一个index,这样一个是不利于查询的效率,一个是不利于后面的删除,既然我们不能index中去删除部分的大批量数据,那么我们为啥不改变一种思路呢,就是分索引,然后通过索引来删除数据,例如:我在生产上面,每天有5亿的数据,那么我每天在集群中生成一个index用于存储这5亿的数据,如果我们的elasticsearch集群对数据只要求保存7天的数据,超过7天的数据就可以删除了,这样我们可以通过index直接删除7天以前的数据,这种方式,我们在查询的时候不会在所有数据中查询,只需要在所要查询的时间段内查询,便提高了查询的效率,同时删除效率的问题也解决了,能够很快删除不需要的数据,释放掉磁盘空间。
针对于elasticsearch大批量数据删除效率的问题,目前官网上面也没有一个特别好的解决办法,这种方式算是目前还算能行得通的方式了。

Elasticsearch 2.0以上版本根据条件批量删除Java如何实现相关推荐

  1. Delete By Query API 条件批量删除

    转载:https://blog.csdn.net/wwd0501/article/details/78812873 之前在 2.X版本里 这个Delete By Query功能被去掉了 因为官方认为会 ...

  2. Linq多表查询条件批量删除

    前阵写了Linq的单表生成相对Sql执行的批量删除,总觉得删除条件太局限了,并且又不能屏蔽linq的级联条件,这很容易误导一些人.所以想了应该还是要支持才好.呵呵. 其实思路和上次一样,就是生成Sql ...

  3. 批量删除java注释_怎样批量去掉java文件中的注释

    展开全部 批量去掉Java文件中的注释,可以e69da5e887aa3231313335323631343130323136353331333337396231使用正则表达式进行批量操作,代码如下:i ...

  4. 批量删微博丨2023简易版本控制台批量删除微博代码

    批量删微博丨简易版批量删除微博方法 微博点击头像到全是自己微博动态的个人主页 复制以下内容到浏览器控制台回车执行 function deleteMessage() {// 下箭头let iDom = ...

  5. JRE和JDK 1.3、1.4、1.5(5.0)、6.0 各版本下载地址大全(J2SDK,JavaSE JavaEE)

    本文转载(http://hi.baidu.com/y66901356/blog/item/7d32bf0abf7d7c3ab0351d39.html) 本人绝对支持原创!!! Java SE Deve ...

  6. java abort_在7.0以上版本的手机系统上出现java.lang.Exception: ... abort cold fix异常

    在7.0以上版本的手机系统上出现java.lang.Exception: - abort cold fix异常,应用崩溃,一般后面还会报出java.lang.ClassNotFoundExceptio ...

  7. 金蝶KIS系列批量删除凭证方法,金蝶记账王、迷你版、标准版通用免费小工具

    本工具弥补了金蝶迷你版/记账王/标准版低端版本不支持批量删除凭证的缺点 支持记账王批量删除凭证,迷你版批量删除凭证,标准版批量删除凭证. 一些因为凭证引入导入错误,无法手工删除的凭证,它也能删除. 为 ...

  8. angularJS 全选反选批量删除

    <th> <label for="flag"> <span ng-hide="master">全选</span> ...

  9. mysql之批量删除

    有时,为了提高数据库的性能,我们采用批量删除,就是一条sql删除1000条这样的数据,相比执行1000条sql的删除命令,性能会大大提高. 这里举个例子说明sql如何写 DBMysql dBMysql ...

最新文章

  1. iOS App上架流程
  2. java hashmapconcurrentHashmap源理
  3. jquery 使用animate来改变高度自动添加样式overflow:hidden的问题
  4. SharePoint 2013 - Callout
  5. python 仿真实验_生成仿真的演化网络实验【Python版】
  6. JDK12的新特性:CompactNumberFormat
  7. django-模板文件加载顺序
  8. 游戏版号重新发放,开发者可以松口气了!| 畅言
  9. C++复习(虚函数)
  10. hadoop 压缩工具 比较
  11. 2017年10月、11月 windows 用360 打最新补丁导致的问题
  12. 线程创建常用的四种方式
  13. 徐思201771010132《面向对象程序设计(Java)》第十二周学习总结
  14. 警告: A docBase D:\apache-tomcat-8.5\webapps\webapps\projectname inside the host appBase has been
  15. 使用随机文件流类RandomAccessFile将一个文本文件倒置读出。
  16. 为什么一个手机有两个mac地址?
  17. 数据告诉你:疯狂联名的背后,藏着喜茶多大的商业野心?
  18. 欺骗的艺术----(5)
  19. [研究方向]什么是深度学习?它到底有多火?
  20. 【厚积薄发系列】C++项目总结17—《WHY C++ ? 王者归来》读后感

热门文章

  1. (Mark)操作系统原理
  2. 【备忘】bounce ease
  3. 读未来产品的设计(1)
  4. [转帖]不要迷失在技术的海洋中
  5. 戴尔 成铭3980台式计算机,能文能武!戴尔成铭3980商用台式机评测
  6. 手动启动 oracle 服务
  7. SSH框架之Spring4专题4:Spring与DAO
  8. mysql分页查询语法
  9. MyBatis中的selectKey
  10. android进度条课设报告,Android开发之进度条ProgressBar的示例代码