zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    复制构造函数
    c++运算符优先级
    std::condition_variable(二)
    std::condition_variable
    std::unique_lock
    std::lock_guard
    Oracle 11gR2 11.2.0.1 ( 11.2.0.1的BUG?):ohasd不能正常启动:ioctl操作:npohasd的问题:【chmod a+wr /var/tmp/.oracle/npohasd】
    bat、cmd、dos窗口:后台调用,不显示黑色的控制台dos(命令行)窗口
    Ubuntu 安装 Oracle11gR2:'install' of makefile '/home/oracle/app/oracle/product/11.2.0/dbhome_1/ctx/lib/ins_ctx.mk'
    Ubuntu 10.04 安装 Oracle11gR2
  • 原文地址:https://www.cnblogs.com/chenyuanbo/p/9973452.html
Copyright © 2011-2022 走看看