实现一个根据条件删除数据的功能:
BoolQueryBuilder query = QueryBuilders.boolQuery();
query.must(QueryBuilders.termQuery("gameId", gameId));
query.must(QueryBuilders.termQuery("serverId", serverId));
query.must(QueryBuilders.termQuery("account", roleId));
doSearchByBulkDelete(0, 10, query, -1);
private void doSearchByBulkDelete(int form, int size, BoolQueryBuilder query, int totalHits) {
SearchResponse res = transportClient.prepareSearch(String.format(INDEX_NAME, "*"))
.setTypes(INDEX_TYPE)
.setQuery(query)
.setFrom(0)
.setSize(size)
.get();
deleteRecord(res);
int intValue = totalHits < 0 ? Long.valueOf(res.getHits().totalHits).intValue() : totalHits;
int length = res.getHits().getHits().length;
int total = form * size + length;
if (total < intValue) {
// 递归查询删除
doSearchByBulkDelete(form + 1, size, query, intValue);
}
}
因为transportClient.prepareSearch()查询出默认只有前10条记录,如果记录大于10条,就需要多次查询删除动作
第一时间想到使用递归来完成查询删除的动作
junit debug运行完美确定全部删除,交付代码
和同事对接后,发生的妖怪的事情。。。每次调用doSearchByBulkDelete()方法时总是只删除了第一页的10条记录,后面的数据都在。。。。
然后在同事电脑上开启debug模式,结果还是可以成功处理,全部删除
然后各种百度。。。找不到对应的内容。。。算了。。。还是看看源码吧
transportClient.prepareSearch(String.format(INDEX_NAME, "*")) .setTypes(INDEX_TYPE) .setQuery(query) .setFrom(0) .setSize(size) .get();
发现get()方法内部的实现:
public Response get() {
return (ActionResponse)this.execute().actionGet();
}
actionGet()
再往下看:
public interface ActionFuture<T> extends Future<T> {
T actionGet();
T actionGet(String var1);
T actionGet(long var1);
T actionGet(long var1, TimeUnit var3);
T actionGet(TimeValue var1);
}
问题好像明白了。。。原来是异步执行的。。。。
然后修改代码:
BoolQueryBuilder query = QueryBuilders.boolQuery();
query.must(QueryBuilders.termQuery("gameId", gameId));
query.must(QueryBuilders.termQuery("serverId", serverId));
query.must(QueryBuilders.termQuery("account", roleId));
doSearchByBulkDelete(query);
private void doSearchByBulkDelete(BoolQueryBuilder query) {
long totalHits;
int size = 10;
do {
SearchResponse res = transportClient.prepareSearch(String.format(INDEX_NAME, "*"))
.setTypes(INDEX_TYPE)
.setQuery(query)
.setFrom(0)
.setSize(size)
.get();
totalHits = res.getHits().totalHits;
deleteRecord(res);
} while (totalHits >= size);//只要有数据就一直重复执行
}
提交代码对接测试。。。完美解决问题。。。
---- QueryBuilders.wildcardQuery("content", "*全*") 使用通配符不能查询到内容的爬坑
创建mapper时,content 的type设置为text,并且使用ik的分词器,导致wildcardQuery有些词可以查出,有些查不出
解决问题:
1:删除索引
2:重新创建索引,mapping,content的type设置为keyword
3:插入数据,查询。。。结果出来了