美文网首页
使用solrj进行solr查询

使用solrj进行solr查询

作者: 发光的鱼 | 来源:发表于2017-05-29 23:07 被阅读0次

    1.构建maven工程,使用spring boot ,添加如下依赖

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
            <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-data-solr</artifactId>
            </dependency>
            <!-- 替换solrj为solr服务器的版本 -->
            <dependency>
                  <groupId>org.apache.solr</groupId>
                  <artifactId>solr-solrj</artifactId>
                  <version>6.5.1</version>
            </dependency>
    </dependencies>
    <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
     </build>
    

    2.编写查询接口IIndexSearch

    public interface IndexSearch {
    
        /**
         * 根据id查询内容
         *
         * @param id
         * @return
         * @throws Exception
         * @Title: search
         * @Description:
         * @return: PageData
         */
        ResultEntity search(String id);
    
        /**
         * @param query
         * @param isHight 是否高亮显示
         * @return
         */
        ResultEntity execute(SolrQuery query, boolean isHight);
    
    }
    
    • 接口ISolrIndexSearch
    public interface ISolrIndexSearch extends IndexSearch {
    
        /**
         * 获取SolrQuery对象
         *
         * @return
         */
        SolrQuery getQuery();
    
        /**
         * 查询
         *
         * @param page    封装分页
         * @param query   查询条件
         * @param isHight 是否高亮显示
         * @return
         */
        ResultEntity search(Page page, SolrQuery query, boolean isHight);
    
    }
    
    • 抽象实现类AbstractSolrIndexSearch
    public abstract class AbstractSolrIndexSearch implements ISolrIndexSearch {
    
        private static final Logger LOGGER = Logger.getLogger(AbstractSolrIndexSearch.class);
    
        @Resource(name = "solrClient")
        protected SolrClient solr;
    
        public abstract SolrQuery setHighlightHandle(SolrQuery query);
    
        public abstract List<PageData> gethighlighDataList(SolrResponse response);
    
        private ResultEntity putResponseMessage(List<PageData> datas, int responseTime, Page page) {
            ResultEntity result = new ResultEntity();
            result.setResults(datas);
            result.setResponseTime(responseTime);
            if (page != null) {
                result.setPage(page);
            }
            return result;
        }
    
        private PageData getSolrDocumentToPageData(SolrDocument document) {
            Iterator<Entry<String, Object>> it = document.iterator();
            PageData pd = new PageData();
            while (it.hasNext()) {
                Entry<String, Object> entry = it.next();
                pd.put(entry.getKey(), entry.getValue());
            }
            return pd;
        }
    
        private List<PageData> getDataFromSolrDocumentList(SolrDocumentList documents) {
            List<PageData> dataList = Lists.newArrayList();
            Iterator<SolrDocument> it = documents.iterator();
            while (it.hasNext()) {
                SolrDocument document = it.next();
                PageData pds = getSolrDocumentToPageData(document);
                dataList.add(pds);
            }
            return dataList;
        }
    
        @Override
        public ResultEntity execute(SolrQuery query, boolean isHight) {
            CompletableFuture<ResultEntity> completableFuture = CompletableFuture.supplyAsync(() -> {
                return getDataAysc(query, isHight);
            });
            return completableFuture.join();
        }
    
        private ResultEntity getDataAysc(SolrQuery query, boolean isHight) {
            ResultEntity result = new ResultEntity();
            QueryResponse response;
            List<PageData> datas;
            try {
                response = solr.query(query);
                int responseTime = response.getQTime();
                SolrDocumentList documents = response.getResults();
                if (isHight) {
                    datas = gethighlighDataList(response);
                } else {
                    datas = getDataFromSolrDocumentList(documents);
                }
                result = putResponseMessage(datas, responseTime, null);
                LOGGER.info("查询参数:" + query.getQuery());
            } catch (SolrServerException e) {
            } catch (IOException e) {
            }
            return result;
        }
    
        @Override
        public ResultEntity search(String id) {
            long start = System.nanoTime();
            SolrQuery query = new SolrQuery();
            query.setQuery(SolrStatementUtils.generateBaseMatchStatement("id", id));
            //ResultEntity result = execute(query);
            ResultEntity result = getDataAysc(query, false);
            long end = System.nanoTime();
            LOGGER.info("异步查询用时:" + (end - start) + "s");
            return result;
        }
    
        public ResultEntity search(Page page, SolrQuery query, boolean isHight) {
            long start = System.nanoTime();
            // 从page中获取传入的参数对象pagedata,是一个map数据结构
            PageData pd = page.getPd();
    
            int showCount = 0;
            int currentPage = 0;
            int totalResult = 0;
    
            if (null != pd.getString("currentPage")) {
                currentPage = Integer.parseInt(pd.getString("currentPage"));
            }
            if (currentPage == 0) {
                currentPage = 1;
            }
            if (null != pd.getString("showCount")) {
                showCount = Integer.parseInt(pd.getString("showCount"));
            } else {
                showCount = Const.SHOW_COUNT;
            }
            query.setStart(showCount * (currentPage - 1)).setRows(showCount);
            if (isHight) {
                query = setHighlightHandle(query);
            }
    
            ResultEntity result = execute(query, isHight);
    
            page.setCurrentPage(currentPage);
            page.setShowCount(showCount);
            page.setTotalResult(totalResult);
            page = makePage(page);
    
            LOGGER.info("查询参数--" + pd);
            LOGGER.info("查询:" + query.toQueryString());
            long end = System.nanoTime();
            LOGGER.info("方法执行时间:" + (end - start));
            return result;
        }
    
        private Page makePage(Page page) {
            page.getTotalPage();
            page.setEntityOrField(true);
            page.getPageStr();
            return page;
        }
    
    }
    
    • 子类去实现抽象类中的的抽象方法SolrIndexSearch
    public class SolrIndexSearch extends AbstractSolrIndexSearch {
        private static final Logger LOGGER = Logger.getLogger(SolrIndexSearch.class);
    
        @Override
        public SolrQuery getQuery() {
            return new SolrQuery();
        }
    
        @Override
        public SolrQuery setHighlightHandle(SolrQuery query) {
            return null;
        }
    
        @Override
        public List<PageData> gethighlighDataList(SolrResponse response) {
            return null;
        }
    
    }
    

    3.编写索引操作接口IndexeWriter

    public interface IndexeWriter {
    
        ResultEntity delete(List<String> ids);
    
        ResultEntity delete(String id);
    
        void deleteAll() throws Exception;
        
        ResultEntity execute(SolrInputDocument document);
    
        ResultEntity update(PageData document);
        
        ResultEntity updataBatch(List<Object> documents);
    
        ResultEntity write(List<Object> document);
    
        ResultEntity write(PageData pd);
    
        /**
         * 创建索引
         *
         * @throws Exception
         * @Title: createIndex
         * @Description:
         * @return: void
         */
        void createIndex(String beginTime);
    
        void commit();
    
        void close();
    
        /**
         * 提交操作释放链接
         */
        void detory();
    
    }
    
    • 抽象实现类AbstractSolrIndexWriter
    public abstract class AbstractSolrIndexWriter implements IndexeWriter {
    
        private static final Logger LOGGER = Logger.getLogger(AbstractSolrIndexWriter.class);
    
        @Resource(name = "concurrentUpdateSolrClient")
        protected SolrClient solr;
    
        private SolrInputDocument getDocument(PageData pd) {
            SolrInputDocument document = new SolrInputDocument();
            Iterator it = pd.keySet().iterator();
            while (it.hasNext()) {
                String key = (String) it.next();
                document.addField(key, pd.get(key));
            }
            return document;
        }
    
        private List<SolrInputDocument> getDocuments(List<PageData> pds) {
            List<SolrInputDocument> datas = Lists.newArrayList();
            for (PageData pd : pds) {
                SolrInputDocument doc = getDocument(pd);
                datas.add(doc);
            }
            return datas;
        }
    
        /**
         * Title: delete
         *
         * @param id
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#delete(java.lang.String)
         */
        @Override
        public ResultEntity delete(String id) {
            ResultEntity result = new ResultEntity();
            UpdateResponse response;
            try {
                response = solr.deleteById(id);
                int resopnseTime = response.getQTime();
                result.setResponseTime(resopnseTime);
                commit();
                LOGGER.info("删除索引:编号--" + id + "用时:" + resopnseTime);
            } catch (SolrServerException e) {
    
            } catch (IOException e) {
    
            }
            return result;
        }
    
        @Override
        public ResultEntity execute(SolrInputDocument document) {
            CompletableFuture<ResultEntity> future = CompletableFuture.supplyAsync(() -> {
                return executeAysc(document);
            });
            return future.join();
        }
    
        private ResultEntity executeAysc(SolrInputDocument document) {
            ResultEntity result = new ResultEntity();
            UpdateRequest request = new UpdateRequest();
            request.setAction(ACTION.COMMIT, false, false);
            request.add(document);
            UpdateResponse response;
            try {
                response = request.process(solr);
                int responseTime = response.getQTime();
                result.setResponseTime(responseTime);
                LOGGER.info("时间:" + new Date() + "用时:" + responseTime);
            } catch (SolrServerException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * Title: write
         *
         * @param pd
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#write(com.jianong.springbootproject.util.PageData)
         */
        @Override
        public ResultEntity write(PageData pd) {
            ResultEntity result = new ResultEntity();
            SolrInputDocument d = getDocument(pd);
            return execute(d);
        }
    
        /**
         * Title: write
         *
         * @param document
         * @return
         * @see com.jianong.springbootproject.util.indexes.indexing.IndexeWriter#write(java.util.List)
         */
        @Override
        public ResultEntity write(List<PageData> documents) {
            ResultEntity result = new ResultEntity();
            List<SolrInputDocument> datas = getDocuments(documents);
            int responseTime = 0;
            try {
                UpdateResponse response = solr.add(datas);
                commit();
                responseTime = response.getQTime();
                result.setResponseTime(responseTime);
                LOGGER.info("添加索引:" + documents.size() + "条--" + "用时:" + responseTime);
            } catch (SolrServerException e) {
    
            } catch (IOException e) {
    
            }
            return result;
        }
    
        private SolrInputDocument getUpdateDocument(PageData pd) {
            Iterator<String> it = pd.keySet().iterator();
            SolrInputDocument document = new SolrInputDocument();
            while (it.hasNext()) {
                String key = it.next();
                if (Objects.equals("id", key)) {
                    document.setField(key, pd.get("id"));
                } else {
                    Map<String, Object> updateMap = Maps.newHashMapWithExpectedSize(1);
                    updateMap.put("set", pd.get(key));
                    document.setField(key, updateMap);
                }
            }
            return document;
        }
    
        private List<SolrInputDocument> getUpdateDocuments(List<PageData> documents) {
            List<SolrInputDocument> datas = Lists.newArrayList();
            for (PageData pd : documents) {
                SolrInputDocument doc = getUpdateDocument(pd);
                datas.add(doc);
            }
            return datas;
        }
    
        /**
         * Title: update
         *
         * @param document
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#update(com.jianong.springbootproject.util.PageData)
         */
        @Override
        public ResultEntity update(PageData document) {
            ResultEntity result = new ResultEntity();
            SolrInputDocument doc = getUpdateDocument(document);
            return execute(doc);
        }
    
        /**
         * Title: updataBatch
         *
         * @param documents
         * @return
         * @see com.jianong.springbootproject.util.indexes.indexing.IndexeWriter#updataBatch(java.util.List)
         */
        @Override
        public ResultEntity updataBatch(List<PageData> documents) {
            ResultEntity result = new ResultEntity();
            int count = 0;
            if (documents.size() < 20) {
                for (PageData document : documents) {
                    result = update(document);
                }
            } else {
                List<SolrInputDocument> datas = getDocuments(documents);
                try {
                    UpdateResponse response = solr.add(datas);
                    commit();
                } catch (Exception e) {
    
                }
            }
            return result;
        }
    
        /**
         * Title: commit
         *
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#commit()
         */
        @Override
        public void commit() {
            try {
                solr.commit();
            } catch (Exception e) {
                LOGGER.error(e);
            }
        }
    
        /**
         * Title: close
         *
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#close()
         */
        @Override
        public void close() {
            try {
                commit();
                solr.close();
            } catch (Exception e) {
                LOGGER.error(e);
            }
        }
    
        /**
         * Title: detory
         *
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#detory()
         */
        @Override
        public void detory() {
            commit();
            close();
        }
    
    }
    
    • 子类实现抽象类中未实现的接口SolrIndexWriter
    public class SolrIndexWriter extends AbstractSolrIndexWriter implements IndexeWriter {
    
        private static final Logger LOGGER = Logger.getLogger(SolrIndexWriter.class);
    
        /**
         * Title: delete
         * 
         * @param ids
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#delete(java.util.List)
         */
        @Override
        public ResultEntity delete(List<String> ids) {
            return null;
        }
    
        /**
         * Title: deleteAll
         * 
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#deleteAll()
         */
        @Override
        public void deleteAll() throws Exception {
            UpdateResponse response = solr.deleteByQuery("*:*");
            int responseTime = response.getQTime();
            solr.commit();
        }
    
        /**
         * Title: createIndex
         * 
         * @param beginTime
         * @throws Exception
         * @see com.jianong.springbootproject.util.indexes.IndexeWriter#createIndex(java.lang.String)
         */
        @Override
        public void createIndex(String beginTime) {
    
        }
    
    }
    

    4.创建solr查询和操作索引的工厂,供外界调用使用SolrManager

    public final class SolrManager {
    
        @Resource(name = "solrIndexSearch")
        private ISolrIndexSearch solrIndexSearch;
    
        @Resource(name = "solrIndexWriter")
        private IndexeWriter indexeWriter;
    
        public SolrQuery getQuery() {
            return solrIndexSearch.getQuery();
        }
    
        public ResultEntity search(String id) {
            return solrIndexSearch.search(id);
        }
    
        /**
         * 删除索引
         *
         * @param ids
         * @throws Exception
         */
        public ResultEntity delete(List<String> ids) {
            return indexeWriter.delete(ids);
        }
    
        public ResultEntity delete(String id) {
            return indexeWriter.delete(id);
        }
    
        public void deleteAll() throws Exception {
            indexeWriter.deleteAll();
        }
    
        public ResultEntity update(PageData document) {
            return indexeWriter.update(document);
        }
    
        public ResultEntity write(List<PageData> document) {
            return indexeWriter.write(document);
        }
    
        public ResultEntity write(PageData pd) {
            return indexeWriter.write(pd);
        }
    
        /**
         * 创建索引
         *
         * @throws Exception
         * @Title: createIndex
         * @Description:
         * @return: void
         */
        public void createIndex(String beginTime) throws Exception {
    
        }
    
        /**
         * 查询
         *
         * @param page
         * @param query
         * @param isHight
         * @return
         * @throws Exception
         */
        public ResultEntity search(Page page, SolrQuery query, boolean isHight) throws Exception {
            return solrIndexSearch.search(page, query, isHight);
        }
    
    }
    

    5.在application.properties中配置solr

    solr.url=http://host:port/solr/
    solr.collection=collectionname
    #是否为集群
    solr.cluster=false
    solr.timeout=10000
    solr.maxconnection=100
    solr.queuesize=20
    #集群中必须配置zookeeper地址
    solr.zookeeper.url=192.168.0.5:2181
    

    6.配置solr,在spring boot启动中,覆盖默认的solrClient配置

    public class SolrConfig implements EnvironmentAware {
    
        private static Logger LOGGER = Logger.getLogger(SolrConfig.class);
    
        private boolean solrCluster = false;
    
        private SolrConfigBean config;
    
        @Override
        public void setEnvironment(Environment environment) {
            config = new SolrConfigBean();
            loadProperties(environment);
        }
    
        private void loadProperties(Environment env) {
            String url = env.getProperty("solr.url");
            int maxConnection = Integer.parseInt(env.getProperty("solr.maxconnection"));
            String collection = env.getProperty("solr.collection");
            int timeout = Integer.parseInt(env.getProperty("solr.timeout"));
            boolean solrIsCluster = Boolean.parseBoolean(env.getProperty("solr.cluster"));
    
            if (solrIsCluster) {
                String zookeeperUrl = env.getProperty("solr.zookeeper.url");
                if (zookeeperUrl.indexOf(",") != -1) {
                    String[] tmp = zookeeperUrl.split(",");
                    List<String> zkList = Lists.newArrayList(tmp);
                    config.setZookeeperUrl(zkList);
                } else {
                    List<String> zkList = Lists.newArrayList(zookeeperUrl);
                    config.setZookeeperUrl(zkList);
                }
            }
    
            config.setTimeout(timeout);
            config.setUrl(url);
            config.setCollection(collection);
            config.setMaxConnection(maxConnection);
            solrCluster = solrIsCluster;
    
        }
    
        @Bean
        public SolrClient solrClient() {
            boolean falg = isSolrCluster();
            if (falg) {
                SolrClient client = new CloudSolrClient.Builder().withZkHost(config.getZookeeperUrl()).build();
                ((CloudSolrClient) client).setDefaultCollection(config.getCollection());
                ((CloudSolrClient) client).setParser(new XMLResponseParser());
                ((CloudSolrClient) client).setRequestWriter(new BinaryRequestWriter());
                return client;
            } else {
                SolrClient solr = new HttpSolrClient.Builder(getSolrUrl()).build();
                ((HttpSolrClient) solr).setParser(new XMLResponseParser());
                ((HttpSolrClient) solr).setRequestWriter(new BinaryRequestWriter());
                ((HttpSolrClient) solr).setConnectionTimeout(config.getTimeout());
                ((HttpSolrClient) solr).setSoTimeout(100000);
                ((HttpSolrClient) solr).setDefaultMaxConnectionsPerHost(config.getMaxConnection());
                return solr;
            }
        }
    
        @Bean
        public ConcurrentUpdateSolrClient concurrentUpdateSolrClient() {
            ConcurrentUpdateSolrClient client =
                    new ConcurrentUpdateSolrClient.Builder(getSolrUrl())
                            .withQueueSize(10)
                            .build();
            client.setRequestWriter(new BinaryRequestWriter());
            client.setParser(new XMLResponseParser());
            return client;
        }
    
        public SolrConfigBean getConfig() {
            return config;
        }
    
        public String getSolrUrl() {
            StringBuffer sb = new StringBuffer();
            sb.append(config.getUrl()).append(config.getCollection());
            return sb.toString();
        }
    
        public boolean isSolrCluster() {
            return solrCluster;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:使用solrj进行solr查询

          本文链接:https://www.haomeiwen.com/subject/yoylfxtx.html