• java使用elasticsearch进行模糊查询之must使用-项目中实际使用


     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的时候,速度会越来越慢,并可能造成宕机。

    精准条件查询

    MatchPhraseQueryBuilder mpq1 = QueryBuilders
                        .matchPhraseQuery("id",knowledgeId);
                qbs.must(mpq1);//主题id

    模糊条件查询

     QueryBuilder qb1 = QueryBuilders.matchPhraseQuery("title", keyword);
    qbs.must(qb1);
     requestBuilder.setQuery(qbs);
  • 相关阅读:
    jquery toggle(listenerOdd, listenerEven)
    struts quick start
    hdu 1518 Square (dfs)
    hdu 2544 最短路 (最短路径)
    hdu 1754 I Hate It (线段树)
    hdu 1856 More is better (并查集)
    hdu 1358 Period (KMP)
    hdu 2616 Kill the monster (DFS)
    hdu 2579 Dating with girls(2) (bfs)
    zoj 2110 Tempter of the Bone (dfs)
  • 原文地址:https://www.cnblogs.com/chenyuanbo/p/9973452.html
Copyright © 2020-2023  润新知