1. 程式人生 > >java使用elasticsearch進行模糊查詢之must使用

java使用elasticsearch進行模糊查詢之must使用

pes setsize itl layui 端口 urn sys prop 設置

java使用elasticsearch進行多個條件模糊查詢

文章說明:

1、本篇文章,本人會從java連接elasticsearch到查詢結果生成並映射到具體實體類(涵蓋分頁功能)

2、代碼背景:elasticsearch版本為:5.2.0;

3、本人以下代碼是分別從兩個索引中查詢數據,再將兩個數據進行整合,如果大家只需要分組查詢,那麽則選取文章中的分組查詢部分代碼

4、本人的實體類主要是按照layUI分頁框架進行設計;實體大家可以根據自己的具體需求進行設計

一、java連接elasticsearch工具類

public class ESClientConnectionUtil {
    
public static TransportClient client=null; public final static String HOST = "192.168.200.200"; //服務器部署ip 根據自己ip進行更改 public final static Integer PORT = 9301; //端口 public static TransportClient getESClient(){ System.setProperty("es.set.netty.runtime.available.processors", "false");
if (client == null) { synchronized (ESClientConnectionUtil.class) { try { //設置集群名稱 Settings settings = Settings.builder().put("cluster.name", "es5").put("client.transport.sniff", true).build(); //創建client client = new
PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(HOST), PORT)); } catch (Exception ex) { ex.printStackTrace(); System.out.println(ex.getMessage()); } } } return client; } public static TransportClient getESClientConnection(){ if (client == null) { System.setProperty("es.set.netty.runtime.available.processors", "false"); try { //設置集群名稱 Settings settings = Settings.builder().put("cluster.name", "es5").put("client.transport.sniff", true).build(); //創建client client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(HOST), PORT)); } catch (Exception ex) { ex.printStackTrace(); System.out.println(ex.getMessage()); } } return client; } //判斷索引是否存在 public static boolean judgeIndex(String index){ client= getESClientConnection(); IndicesAdminClient adminClient; //查詢索引是否存在 adminClient= client.admin().indices(); IndicesExistsRequest request = new IndicesExistsRequest(index); IndicesExistsResponse responses = adminClient.exists(request).actionGet(); if (responses.isExists()) { return true; } return false; } }

二、實體類

(一)分頁實體總類

public class KnowledgeTopicListDTO {
   private Long totalCount;//總條數
   private Integer page;//頁數
   private Integer limit;//每頁查詢條數
   private List<KnowledgeTopicDTO> topicDTOList;//每頁顯示數據的對象集合

    public Long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(Long totalCount) {
        this.totalCount = totalCount;
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public List<KnowledgeTopicDTO> getTopicDTOList() {
        return topicDTOList;
    }

    public void setTopicDTOList(List<KnowledgeTopicDTO> topicDTOList) {
        this.topicDTOList = topicDTOList;
    }
}

(二)頁面顯示數據對象實體

public class KnowledgeTopicDTO {
    private Long id;//知識主題id
    private String name;//知識主題名稱
    private Boolean active;//有效無效 true,false
    private String activeString;//有效無效
    private Boolean noSubscription;//是否需要訂閱 true,false
    private String noSubscriptionString;//是否需要訂閱
    private Long quantity;//數據量
    private String _id;
    private String ids;

    public String getIds() {
        return ids;
    }

    public void setIds(String ids) {
        this.ids = ids;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public String getActiveString() {
        return activeString;
    }

    public void setActiveString(String activeString) {
        this.activeString = activeString;
    }

    public Boolean getNoSubscription() {
        return noSubscription;
    }

    public void setNoSubscription(Boolean noSubscription) {
        this.noSubscription = noSubscription;
    }

    public String getNoSubscriptionString() {
        return noSubscriptionString;
    }

    public void setNoSubscriptionString(String noSubscriptionString) {
        this.noSubscriptionString = noSubscriptionString;
    }

    public Long getQuantity() {
        return quantity;
    }

    public void setQuantity(Long quantity) {
        this.quantity = quantity;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }
}

三、後臺service層代碼

 public KnowledgeTopicListDTO selectTopicByName(String name, Integer page, Integer limit) {
        SearchResponse searchResponse=null;
        Map<String,Object> map = new HashMap<>();
        TransportClient transportClient =  ESClientConnectionUtil.getESClientConnection();
            SearchRequestBuilder requestBuilder = client.prepareSearch("knowledge").setTypes("knowledge_theme");
            // 聲明where條件
            BoolQueryBuilder qbs = QueryBuilders.boolQuery();
            /**此處使用模糊匹配查詢 類比數據庫中 like*/
            QueryBuilder qb1 = QueryBuilders.matchPhraseQuery("name", name);
            BoolQueryBuilder bqb1 = QueryBuilders.boolQuery().must(qb1);
            qbs.must(bqb1);
            requestBuilder.setQuery(qbs);
            int num=limit*(page-1);
            SearchResponse response = requestBuilder.setFrom(0).setSize(10).execute().actionGet();
            //獲取總條數
//        long totalCount = searchResponse.getHits().getTotalHits();
            List<KnowledgeTopicDTO> list = new ArrayList<KnowledgeTopicDTO>();
            for (SearchHit hit : response.getHits().getHits()) {
                //獲取到當前頁的數據
                JSONObject obj = new JSONObject().fromObject(hit.getSourceAsString());//將json字符串轉換為json對象
                KnowledgeTopicDTO topic = (KnowledgeTopicDTO) JSONObject.toBean(obj, KnowledgeTopicDTO.class);//將建json對象轉換為Person對象
                list.add(topic);
            }
            //查詢主題總數
        Terms terms= ESGroupByUtil.GroupByOne(client,"hottopic","hot","sum","tasktitleid");
        list= groupList(list,terms);//調用組合主題總數方法
        KnowledgeTopicListDTO knowledgeTopicListDTO = new KnowledgeTopicListDTO();
        knowledgeTopicListDTO.setLimit(limit);
        knowledgeTopicListDTO.setPage(page);
        knowledgeTopicListDTO.setTopicDTOList(list);
        return knowledgeTopicListDTO;
    }

五、根據單個字段分組查詢

public class ESGroupByUtil {

    /**
     *@description: 根據單個字段分組求和
     *@author:cyb
     *@date: 2018-11-16 17:31
    *@param: client ES連接
    *@param: indices 索引
    *@param: types 類型
    *@param: alias 分組求和別名
    *@param: DomName 分組目標字段名
     *@return: org.elasticsearch.search.aggregations.bucket.terms.Terms
     */
    public static Terms GroupByOne(TransportClient client,String indices,String types,String alias,String DomName){
        SearchRequestBuilder sbuilder = client.prepareSearch(indices).setTypes(types);
        TermsAggregationBuilder termsBuilder = AggregationBuilders.terms(alias).field(DomName);
        sbuilder.addAggregation(termsBuilder);
        SearchResponse responses= sbuilder.execute().actionGet();
        Terms terms = responses.getAggregations().get(alias);
        return terms;
    }


}

六 、將分組查詢的數據進行整合到已查詢到的集合中

 /**
     *@description:將查詢的總數合並到list中
     *@author:cyb
     *@date: 2018-11-16 17:51
    *@param: list
    *@param: terms
     *@return: java.util.List<com.yjlc.platform.bsKnowledge.KnowledgeTopicDTO>
     */
      public List<KnowledgeTopicDTO> groupList(List<KnowledgeTopicDTO> list,Terms terms){
        List<BsKnowledgeInfoDTO> lists = new ArrayList<>();
        for(int i=0;i<terms.getBuckets().size();i++){
            //statistics
            String id =terms.getBuckets().get(i).getKey().toString();//id
            Long sum =terms.getBuckets().get(i).getDocCount();//數量
            BsKnowledgeInfoDTO bsKnowledgeInfoDTO1 = new BsKnowledgeInfoDTO();
            bsKnowledgeInfoDTO1.setId(id);
            bsKnowledgeInfoDTO1.setSum(sum);
            lists.add(bsKnowledgeInfoDTO1);
            System.out.println("=="+ terms.getBuckets().get(i).getDocCount()+"------"+terms.getBuckets().get(i).getKey());
        }
        for(int i=0;i<lists.size();i++){
            for(int j=0;j<list.size();j++){
                if(lists.get(i).getId().equals(list.get(j).getId())){
                    list.get(j).setQuantity(lists.get(i).getSum());
                }
            }
        }

        return list;
    }

總結:以上代碼是本人的親自測試通過的,分頁後期建議大家不用使用from,size格式,當數據量超過1w的時候,速度會越來越慢,並可能造成宕機。

java使用elasticsearch進行模糊查詢之must使用