上一篇讲了通过http请求对ElasticSearch的增删改查操作,java也提供了相应的api来完成这些操作,这一篇是根据java的api封装的工具类。
这是针对ES查询的一套封装。 因为时间有限仅仅能够支持一些简单查询,但能满足大部分开发需求。
同时也封装了对索引以及数据的CRUD、批量处理。
1. public static void main(String[] args) {
2. try {
3. new ElasticSearchService("es", "192.168.1.1", 9300);
4. new ESQueryBuilderConstructor();
5. new ESQueryBuilders().term("gender", "f").range("age", 20, 50));
6. new ESQueryBuilders().term("gender", "f").range("age", 20, 50).fuzzy("age", 20));
7. new ESQueryBuilders().term("gender", "m"));
8. 15); //查询返回条数,最大 10000
9. 11); //分页查询条目起始位置, 默认0
10. "age"); //排序
11.
12. "bank", "account", constructor);
13. "bank", "account", constructor, "state");
14.
15. catch (Exception e) {
16. e.printStackTrace();
17. }
18. }
条件接口
1. import org.elasticsearch.index.query.QueryBuilder;
2. import java.util.List;
3.
4. public interface ESCriterion {
5. public enum Operator {
6. TERM, TERMS, RANGE, FUZZY, QUERY_STRING, MISSING
7. }
8.
9. public enum MatchMode {
10. START, END, ANYWHERE
11. }
12.
13. public enum Projection {
14. MAX, MIN, AVG, LENGTH, SUM, COUNT
15. }
16.
17. public List<QueryBuilder> listBuilders();
18. }
查询条件容器
1. import org.apache.commons.collections.CollectionUtils;
2. import org.elasticsearch.index.query.BoolQueryBuilder;
3. import org.elasticsearch.index.query.QueryBuilder;
4. import org.elasticsearch.index.query.QueryBuilders;
5.
6. import java.util.ArrayList;
7. import java.util.List;
8. public class ESQueryBuilderConstructor {
9.
10. private int size = Integer.MAX_VALUE;
11.
12. private int from = 0;
13.
14. private String asc;
15.
16. private String desc;
17.
18. //查询条件容器
19. private List<ESCriterion> mustCriterions = new ArrayList<>();
20. private List<ESCriterion> shouldCriterions = new ArrayList<>();
21. private List<ESCriterion> mustNotCriterions = new ArrayList<>();
22.
23. //构造builder
24. public QueryBuilder listBuilders() {
25. int count = mustCriterions.size() + shouldCriterions.size() + mustNotCriterions.size();
26. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
27. null;
28.
29. if (count >= 1) {
30. //must容器
31. if (!CollectionUtils.isEmpty(mustCriterions)) {
32. for (ESCriterion criterion : mustCriterions) {
33. for (QueryBuilder builder : criterion.listBuilders()) {
34. queryBuilder = boolQueryBuilder.must(builder);
35. }
36. }
37. }
38. //should容器
39. if (!CollectionUtils.isEmpty(shouldCriterions)) {
40. for (ESCriterion criterion : shouldCriterions) {
41. for (QueryBuilder builder : criterion.listBuilders()) {
42. queryBuilder = boolQueryBuilder.should(builder);
43. }
44.
45. }
46. }
47. //must not 容器
48. if (!CollectionUtils.isEmpty(mustNotCriterions)) {
49. for (ESCriterion criterion : mustNotCriterions) {
50. for (QueryBuilder builder : criterion.listBuilders()) {
51. queryBuilder = boolQueryBuilder.mustNot(builder);
52. }
53. }
54. }
55. return queryBuilder;
56. else {
57. return null;
58. }
59. }
60.
61. /**
62. * 增加简单条件表达式
63. */
64. public ESQueryBuilderConstructor must(ESCriterion criterion){
65. if(criterion!=null){
66. mustCriterions.add(criterion);
67. }
68. return this;
69. }
70. /**
71. * 增加简单条件表达式
72. */
73. public ESQueryBuilderConstructor should(ESCriterion criterion){
74. if(criterion!=null){
75. shouldCriterions.add(criterion);
76. }
77. return this;
78. }
79. /**
80. * 增加简单条件表达式
81. */
82. public ESQueryBuilderConstructor mustNot(ESCriterion criterion){
83. if(criterion!=null){
84. mustNotCriterions.add(criterion);
85. }
86. return this;
87. }
88.
89.
90. public int getSize() {
91. return size;
92. }
93.
94. public void setSize(int size) {
95. this.size = size;
96. }
97.
98. public String getAsc() {
99. return asc;
100. }
101.
102. public void setAsc(String asc) {
103. this.asc = asc;
104. }
105.
106. public String getDesc() {
107. return desc;
108. }
109.
110. public void setDesc(String desc) {
111. this.desc = desc;
112. }
113.
114. public int getFrom() {
115. return from;
116. }
117.
118. public void setFrom(int from) {
119. this.from = from;
120. }
121. }
条件构造器
1. import org.elasticsearch.index.query.QueryBuilder;
2.
3. import java.util.ArrayList;
4. import java.util.Collection;
5. import java.util.List;
6. public class ESQueryBuilders implements ESCriterion{
7.
8. private List<QueryBuilder> list = new ArrayList<>();
9.
10. /**
11. * 功能描述:Term 查询
12. * @param field 字段名
13. * @param value 值
14. */
15. public ESQueryBuilders term(String field, Object value) {
16. new ESSimpleExpression (field, value, Operator.TERM).toBuilder());
17. return this;
18. }
19.
20. /**
21. * 功能描述:Terms 查询
22. * @param field 字段名
23. * @param values 集合值
24. */
25. public ESQueryBuilders terms(String field, Collection<Object> values) {
26. new ESSimpleExpression (field, values).toBuilder());
27. return this;
28. }
29.
30. /**
31. * 功能描述:fuzzy 查询
32. * @param field 字段名
33. * @param value 值
34. */
35. public ESQueryBuilders fuzzy(String field, Object value) {
36. new ESSimpleExpression (field, value, Operator.FUZZY).toBuilder());
37. return this;
38. }
39.
40. /**
41. * 功能描述:Range 查询
42. * @param from 起始值
43. * @param to 末尾值
44. */
45. public ESQueryBuilders range(String field, Object from, Object to) {
46. new ESSimpleExpression (field, from, to).toBuilder());
47. return this;
48. }
49.
50. /**
51. * 功能描述:Range 查询
52. * @param queryString 查询语句
53. */
54. public ESQueryBuilders queryString(String queryString) {
55. new ESSimpleExpression (queryString, Operator.QUERY_STRING).toBuilder());
56. return this;
57. }
58.
59. public List<QueryBuilder> listBuilders() {
60. return list;
61. }
62. }
条件表达式
1. import org.elasticsearch.index.query.QueryBuilder;
2. import org.elasticsearch.index.query.QueryBuilders;
3.
4. import java.util.Collection;
5.
6. import static com.scistor.label.labelstore.elasticsearch.ESCriterion.Operator;
7. public class ESSimpleExpression {
8. private String fieldName; //属性名
9. private Object value; //对应值
10. private Collection<Object> values; //对应值
11. private ESCriterion.Operator operator; //计算符
12. private Object from;
13. private Object to;
14.
15. protected ESSimpleExpression(String fieldName, Object value, Operator operator) {
16. this.fieldName = fieldName;
17. this.value = value;
18. this.operator = operator;
19. }
20.
21. protected ESSimpleExpression(String value, Operator operator) {
22. this.value = value;
23. this.operator = operator;
24. }
25.
26. protected ESSimpleExpression(String fieldName, Collection<Object> values) {
27. this.fieldName = fieldName;
28. this.values = values;
29. this.operator = Operator.TERMS;
30. }
31.
32. protected ESSimpleExpression(String fieldName, Object from, Object to) {
33. this.fieldName = fieldName;
34. this.from = from;
35. this.to = to;
36. this.operator = Operator.RANGE;
37. }
38.
39. public QueryBuilder toBuilder() {
40. null;
41. switch (operator) {
42. case TERM:
43. qb = QueryBuilders.termQuery(fieldName, value);
44. break;
45. case TERMS:
46. qb = QueryBuilders.termsQuery(fieldName, values);
47. break;
48. case RANGE:
49. true).includeUpper(true);
50. break;
51. case FUZZY:
52. qb = QueryBuilders.fuzzyQuery(fieldName, value);
53. break;
54. case QUERY_STRING:
55. qb = QueryBuilders.queryStringQuery(value.toString());
56. }
57. return qb;
58. }
59. }
ES检索封装
package com.example.demo.util;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.sort.SortOrder;
import java.net.InetSocketAddress;
import java.util.*;
/**
* Created by admin on 17/6/2.
*/
public class ElasticSearchService {
private final static int MAX = 10000;
TransportClient client;
/**
* 功能描述:服务初始化
*
* @param clusterName 集群名称
* @param ip 地址
* @param port 端口
*/
public ElasticSearchService(String clusterName, String ip, int port) {
Settings setting = Settings.builder()
//集群名称
.put("cluster.name", clusterName)
.put("client.transport.sniff", true)
.put("client.transport.ignore_cluster_name", false)
.put("client.transport.ping_timeout", "5s")
.put("client.transport.nodes_sampler_interval", "5s")
.build();
if (client == null) {
try {
client = TransportClient.builder().settings(setting).build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ip), port));
} catch (UnknownHostException e) {
e.printStackTrace();
}
} } /** * 功能描述:新建索引 * * @param indexName 索引名 */ public void createIndex(String indexName) { client.admin().indices().create(new CreateIndexRequest(indexName)) .actionGet(); } /** * 功能描述:新建索引 * * @param index 索引名 * @param type 类型 */ public void createIndex(String index, String type) { client.prepareIndex(index, type).setSource().get(); } /** * 功能描述:删除索引 * * @param index 索引名 */ public void deleteIndex(String index) { if (indexExist(index)) { DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index) .execute().actionGet(); if (!dResponse.isAcknowledged()) { throw new MessageException("failed to delete index."); } } else { throw new MessageException("index name not exists"); } } /** * 功能描述:验证索引是否存在 * * @param index 索引名 */ public boolean indexExist(String index) { IndicesExistsRequest inExistsRequest = new IndicesExistsRequest(index); IndicesExistsResponse inExistsResponse = client.admin().indices() .exists(inExistsRequest).actionGet(); return inExistsResponse.isExists(); } /** * 功能描述:插入数据 * * @param index 索引名 * @param type 类型 * @param json 数据 */ public void insertData(String index, String type, String json) { IndexResponse response = client.prepareIndex(index, type) .setSource(json) .get(); } /** * 功能描述:插入数据 * * @param index 索引名 * @param type 类型 * @param _id 数据id * @param json 数据 */ public void insertData(String index, String type, String _id, String json) { IndexResponse response = client.prepareIndex(index, type).setId(_id) .setSource(json) .get(); } /** * 功能描述:更新数据 * * @param index 索引名 * @param type 类型 * @param _id 数据id * @param json 数据 */ public void updateData(String index, String type, String _id, String json) throws Exception { try { UpdateRequest updateRequest = new UpdateRequest(index, type, _id) .doc(json); client.update(updateRequest).get(); } catch (Exception e) { throw new MessageException("update data failed.", e); } } /** * 功能描述:删除数据 * * @param index 索引名 * @param type 类型 * @param _id 数据id */ public void deleteData(String index, String type, String _id) { DeleteResponse response = client.prepareDelete(index, type, _id) .get(); } /** * 功能描述:批量插入数据 * * @param index 索引名 * @param type 类型 * @param data (_id 主键, json 数据) */ public void bulkInsertData(String index, String type, Map<String, String> data) { BulkRequestBuilder bulkRequest = client.prepareBulk(); data.forEach((param1, param2) -> { bulkRequest.add(client.prepareIndex(index, type, param1) .setSource(param2) ); }); BulkResponse bulkResponse = bulkRequest.get(); } /** * 功能描述:批量插入数据 * * @param index 索引名 * @param type 类型 * @param jsonList 批量数据 */ public void bulkInsertData(String index, String type, List<String> jsonList) { BulkRequestBuilder bulkRequest = client.prepareBulk(); jsonList.forEach(item -> { bulkRequest.add(client.prepareIndex(index, type) .setSource(item) ); }); BulkResponse bulkResponse = bulkRequest.get(); } /** * 功能描述:查询 * * @param index 索引名 * @param type 类型 * @param constructor 查询构造 */ public List<Map<String, Object>> search(String index, String type, ESQueryBuilderConstructor constructor) { List<Map<String, Object>> result = new ArrayList<>(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type); //排序 if (StringUtils.isNotEmpty(constructor.getAsc())) searchRequestBuilder.addSort(constructor.getAsc(), SortOrder.ASC); if (StringUtils.isNotEmpty(constructor.getDesc())) searchRequestBuilder.addSort(constructor.getDesc(), SortOrder.DESC); //设置查询体 searchRequestBuilder.setQuery(constructor.listBuilders()); //返回条目数 int size = constructor.getSize(); if (size < 0) { size = 0; } if (size > MAX) { size = MAX; } //返回条目数 searchRequestBuilder.setSize(size); searchRequestBuilder.setFrom(constructor.getFrom() < 0 ? 0 : constructor.getFrom()); SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); SearchHits hits = searchResponse.getHits(); SearchHit[] searchHists = hits.getHits(); for (SearchHit sh : searchHists) { result.add(sh.getSource()); } return result; } /** * 功能描述:统计查询 * * @param index 索引名 * @param type 类型 * @param constructor 查询构造 * @param groupBy 统计字段 */ public Map<Object, Object> statSearch(String index, String type, ESQueryBuilderConstructor constructor, String groupBy) { Map<Object, Object> map = new HashMap(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type); //排序 if (StringUtils.isNotEmpty(constructor.getAsc())) searchRequestBuilder.addSort(constructor.getAsc(), SortOrder.ASC); if (StringUtils.isNotEmpty(constructor.getDesc())) searchRequestBuilder.addSort(constructor.getDesc(), SortOrder.DESC); //设置查询体 if (null != constructor) { searchRequestBuilder.setQuery(constructor.listBuilders()); } else { searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); } int size = constructor.getSize(); if (size < 0) { size = 0; } if (size > MAX) { size = MAX; } //返回条目数 searchRequestBuilder.setSize(size); searchRequestBuilder.setFrom(constructor.getFrom() < 0 ? 0 : constructor.getFrom()); SearchResponse sr = searchRequestBuilder.addAggregation( AggregationBuilders.terms("agg").field(groupBy) ).get(); Terms stateAgg = sr.getAggregations().get("agg"); Iterator<Terms.Bucket> iter = stateAgg.getBuckets().iterator(); while (iter.hasNext()) { Terms.Bucket gradeBucket = iter.next(); map.put(gradeBucket.getKey(), gradeBucket.getDocCount()); } return map; } /** * 功能描述:统计查询 * * @param index 索引名 * @param type 类型 * @param constructor 查询构造 * @param agg 自定义计算 */ public Map<Object, Object> statSearch(String index, String type, ESQueryBuilderConstructor constructor, AggregationBuilder agg) { if (agg == null) { return null; } Map<Object, Object> map = new HashMap(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type); //排序 if (StringUtils.isNotEmpty(constructor.getAsc())) searchRequestBuilder.addSort(constructor.getAsc(), SortOrder.ASC); if (StringUtils.isNotEmpty(constructor.getDesc())) searchRequestBuilder.addSort(constructor.getDesc(), SortOrder.DESC); //设置查询体 if (null != constructor) { searchRequestBuilder.setQuery(constructor.listBuilders()); } else { searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); } int size = constructor.getSize(); if (size < 0) { size = 0; } if (size > MAX) { size = MAX; } //返回条目数 searchRequestBuilder.setSize(size); searchRequestBuilder.setFrom(constructor.getFrom() < 0 ? 0 : constructor.getFrom()); SearchResponse sr = searchRequestBuilder.addAggregation( agg ).get(); Terms stateAgg = sr.getAggregations().get("agg"); Iterator<Terms.Bucket> iter = stateAgg.getBuckets().iterator(); while (iter.hasNext()) { Terms.Bucket gradeBucket = iter.next(); map.put(gradeBucket.getKey(), gradeBucket.getDocCount()); } return map; } /** * 功能描述:关闭链接 */ public void close() { client.close(); }}