zoukankan      html  css  js  c++  java
  • java优雅的使用elasticsearch api

    本文给出一种优雅的拼装elasticsearch查询的方式,可能会使得使用elasticsearch的方式变得优雅起来,使得代码结构很清晰易读。

    建立elasticsearch连接部分请参看另一篇博客:http://www.cnblogs.com/kangoroo/p/7127003.html

    1、ESDao -- 类似DB中的dao层

    封装了增删改查ES的各种方法

    package com.dqa.sentinel.client.es;
    
    import com.xiaoju.dqa.sentinel.client.es.entity.ESDocument;
    import com.xiaoju.dqa.sentinel.client.es.entity.SearchDocument;
    import org.elasticsearch.action.delete.DeleteResponse;
    import org.elasticsearch.index.query.*;
    import org.elasticsearch.search.SearchHits;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.action.get.GetResponse;
    import org.elasticsearch.action.get.MultiGetItemResponse;
    import org.elasticsearch.action.get.MultiGetRequestBuilder;
    import org.elasticsearch.action.get.MultiGetResponse;
    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.action.update.UpdateResponse;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.sort.SortOrder;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.nio.charset.Charset;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    
    import static org.elasticsearch.index.query.QueryBuilders.termQuery;
    import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
    
    
    @Component
    public class ESDao {
    
        @Autowired
        private ESClient esClient;
    
        public void createCache(ESDocument doc) throws Exception {
            IndexResponse response = esCache.getClient().prepareIndex(doc.getIndexName(), doc.getTypeName(), doc.getId())
                    .setSource(doc.getSource().getBytes(Charset.forName("UTF-8"))).setRefresh(true).get();
            if (!response.isCreated()) {
                throw new Exception();
            }
        }
    
        public Map<String, Object> get(ESDocument doc) throws Exception {
            try {
                GetResponse response = esClient.getClient().prepareGet(doc.getIndexName(), doc.getTypeName(), doc.getId()).get();
                return response.getSourceAsMap();
            } catch (Exception ex) {
                throw new Exception();
            }
        }
    
        public void create(ESDocument doc) throws Exception {
            IndexResponse response = esClient.getClient().prepareIndex(doc.getIndexName(), doc.getTypeName(), doc.getId())
                    .setSource(doc.getSource().getBytes(Charset.forName("UTF-8"))).setRefresh(true).get();
            if (!response.isCreated()) {
                throw new Exception();
            }
        }
    
        public void mutiGet(List<ESDocument> docList) throws Exception {
            MultiGetRequestBuilder multiGetRequestBuilder = esClient.getClient().prepareMultiGet();
    
            for (ESDocument doc : docList) {
                multiGetRequestBuilder.add(doc.getIndexName(), doc.getTypeName(), doc.getId());
            }
            MultiGetResponse multiGetItemResponses = multiGetRequestBuilder.get();
    
            for (MultiGetItemResponse itemResponse : multiGetItemResponses) {
                GetResponse response = itemResponse.getResponse();
                if (response.isExists()) {
                    String json = response.getSourceAsString();
                    System.out.println(json);
                }
            }
        }
    
        public void update(ESDocument doc) throws Exception {
            try {
                UpdateRequest request = new UpdateRequest().index(doc.getIndexName())
                        .type(doc.getTypeName()).id(doc.getId())
                        .doc(doc.getSource().getBytes(Charset.forName("UTF-8"))).refresh(true);
                UpdateResponse response = esClient.getClient().update(request).get();
                long docVersion = response.getVersion();
                if (!response.isCreated()) {
                    throw new Exception();
                }
            } catch (Exception e) {
                throw new Exception();
            }
        }
    
        public void deleteById(ESDocument doc) throws Exception{
            try {
                DeleteResponse response = esClient.getClient().prepareDelete(doc.getIndexName(),
                        doc.getTypeName(), doc.getId())
                        .execute()
                        .actionGet();
                long docVersion = response.getVersion();
                if (!response.isFound()) {
                    throw new Exception();
                }
            } catch (Exception e) {
                throw new Exception();
            }
    
        }
    
        public SearchHit[] searchClient(SearchDocument searchDocument) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            // term
            for (Map<String, String> termMap : searchDocument.getTermList()) {
                TermQueryBuilder termQueryBuilder = termQuery(termMap.get("field"), termMap.get("value"));
                query.must(termQueryBuilder);
            }
            // terms
            for (Map<String, Object> termsMap : searchDocument.getTermsList()) {
                if (termsMap.size() != 0) {
                    TermsQueryBuilder termsQueryBuilder = termsQuery(termsMap.get("field").toString(), (Collection<?>) termsMap.get("terms"));
                    query.must(termsQueryBuilder);
                }
            }
            // range
            for (Map rangeMap : searchDocument.getRangeList()) {
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(rangeMap.get("field").toString()).from(rangeMap.get("from")).to(rangeMap.get("to")).includeLower(true).includeUpper(false);
                query.must(rangeQueryBuilder);
            }
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(query);
            SearchRequestBuilder searchRequestBuilder = esClient.getClient()
                    .prepareSearch(searchDocument.getIndexName()).setTypes(searchDocument.getTypeName());
            SearchResponse response = searchRequestBuilder
                    .setQuery(query)
                    .setFrom(0).setSize(10000)
                    .setExplain(true).execute().actionGet();
            SearchHits hits = response.getHits();
            return hits.getHits();
        }
    
        

    2、查询字段的传入我们是通过Document类完成的

    有三个Document,BaseDocument,ESDocument,SearchDocument,后两个继承前一个。

    BaseDocument:

    public class BaseDocument {
        private String indexName;
        private String typeName;
    
        public String getIndexName() {
            return this.indexName;
        }
        public void setIndexName(String indexName) {
            this.indexName = indexName;
        }
        public String getTypeName() {
            return this.typeName;
        }
        public void setTypeName(String typeName) {
            this.typeName = typeName;
        }
    
    }

    ESDocument:

    public class ESDocument extends BaseDocument {
        private String id;
        private String source;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getSource() {
            return source;
        }
        public void setSource(String source) {
            this.source = source;
        }
    
    }

    SearchDocument

    public class SearchDocument extends BaseDocument {
        private List<Map<String, String>> termList;
        private List<Map<String, String>> rangeList;
        private List<Map<String, Object>> termsList;
        public SearchDocument() {
            super();
            termList = new ArrayList<>();
            rangeList = new ArrayList<>();
            termsList = new ArrayList<>();
        }
        public List<Map<String, String>> getTermList() {
            return this.termList;
        }
        public void setTermList(List<Map<String, String>> termList) {
            this.termList = termList;
        }
        public List<Map<String, String>> getRangeList() {
            return this.rangeList;
        }
        public void setRangeList(List<Map<String, String>> rangeList) {
            this.rangeList = rangeList;
        }
    
        public void setTermsList(List<Map<String, Object>> termsList) {
            this.termsList = termsList;
        }
        public List<Map<String, Object>> getTermsList() {
            return termsList;
        }
    }

    3、使用的时候,拼装Document,并通过ESDao查询即可

    例如:

         SearchDocument searchDocument = new SearchDocument();
            // term查询, field:topicName
            Map<String, String> topicMap = new HashMap<>();
            topicMap.put("field", "topicName");
            topicMap.put("value", topicName.toLowerCase());
            List<Map<String, String>> termList = new ArrayList<>();
            termList.add(topicMap);
    
            // range查询, field:timestamp
            Map<String, String> timeRange =  new HashMap<>();
            timeRange.put("field", "timestamp");
            timeRange.put("from", from);
            timeRange.put("to", to);
            List<Map<String, String>> rangeList = new ArrayList<>();
            rangeList.add(timeRange);
    
            searchDocument.setTermList(termList);
            searchDocument.setRangeList(rangeList);
            searchDocument.setIndexName("audit");
            searchDocument.setTypeName("kafka");
            SearchHit[] searchHits = esDao.searchCache(searchDocument);
            String hourStatus = "0";
            for (SearchHit hit : searchHits) {
                Map<String, Object> eachMap = hit.getSource();
        }
  • 相关阅读:
    <大学祭>
    使用rest方式修改服务端xml文件
    tsql的奇特语法
    Dandelion
    正则中关于修饰符g以及exec和match区别的一个小demo
    如何将一个盒子在显示在浏览器的正中间
    Js中的this指向问题
    CSS通过边框border-style来写小三角
    用单例模式封装常用方法 utils class v1.0
    JS中检测数据类型的四种方法
  • 原文地址:https://www.cnblogs.com/kangoroo/p/7136781.html
Copyright © 2011-2022 走看看