上一篇讲了通过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(); }}