荒淫来到狗窝

solr spring 简单封装

版本Solr6

   代码参考github地址:https://github.com/suyin58/spring_solr 

实现功能

1.区分环境:不同的环境下,需要进行区分,例如开发环境、主干测试环境、线上测试环境能够进行隔离,不能相互影响(通过collection)

2.区分业务:不用业务场景的搜索需要进行区分,例如文章搜索、客服问题搜索需要进行隔离,不能相互影响(通过collection)

3.项目启动时候,能够自动创建相关配置,相关collection集群,避免多环境情况下需要进行重复配置

4.提供简单的增删改查功能:(此处solr的schema配置使用简单的ID+content_sa)

实现思路:

1.通过Spring的方式对Bean进行管理

    <!-- 搜索引擎-->
    <bean id="searchEngine" class="com.wjs.common.search.impl.SearchEngineSolrImpl">
        <!-- # zookeeper地址 公用 -->
        <property name="zkHost" value="${system.zookeeper.address}" />
        <!-- # app应用环境 公用 -->
        <property name="appEnv" value="${system.appenv.name}" />
        <!-- # solr 搜索区分业务 -->
        <property name="searchCore" value="${search.solr.core.name}" />
        <!-- # solr 每次接口调用超时时间 -->
        <property name="timeOut" value="${search.solr.timeout}" />
        <!-- # solr 配置,如果search.solr.core.name在集群中不存在,那么初始化solr的配置
            #search.solr.configpath=solr_help_center_config/  示例目录为:classpath:solr_help_center_config/
        -->
        <property name="cfgPath" value="${search.solr.configpath}" />
        <!-- # solr 如果search.solr.core.name在集群中不存在,那么初始化集群的分片数量,构造函数中使用,建议与solr集群数量同步 -->
        <property name="numShards" value="${search.solr.numshards}" />
    </bean>

2.SearchEngineSolrImpl初始化的时候,需要执行如下操作

  2.1.通过appEnv和searchCore构建所需的solr分区名称(collectionName)

  2.2.查看配置的collection是否存在(通过CollectionAdminRequest.List查询)

  2.3.如果不存在

    2.3.1.上传solr配置(通过org.apache.solr.cloud.ZkCLI命令进行配置的上传)

    2.3.2.创建collection(通过CollectionAdminRequest.Create进行collection的创建)

  2.4. 连接collectionName

  

@PostConstruct
    public void init() {

        collectionName = appEnv + "_" + searchCore;
        // 查看collection是否存在,如果不存在需要构建collection
        createCollectionWhenNotExist();
        cloudSolrClient = new CloudSolrClient(zkHost);
        cloudSolrClient.setDefaultCollection(collectionName);
        cloudSolrClient.setZkClientTimeout(timeOut);
        cloudSolrClient.setZkConnectTimeout(3000);
        try {
            cloudSolrClient.connect();
        } catch (Exception e) {
            LOGGER.error("solr connect error:{}", e.getMessage(), e);
        }
    }

    private void createCollectionWhenNotExist() {
        /**
         * 查看配置的collection是否存在,如果不存在,1.上传solr配置.2.创建collection
         */

        CloudSolrClient solrClient = new CloudSolrClient(zkHost);
        solrClient.connect();
        // 通过查询Collection的分布式情况,判断是否存在collection
        CollectionAdminRequest.List collectionList = new CollectionAdminRequest.List();
        ArrayList<String> collectionNames = new ArrayList<String>();
        try {
            CollectionAdminResponse response = collectionList.process(solrClient);
            LinkedTreeMap<String, Object> responseMap = (LinkedTreeMap<String, Object>) gson.fromJson(response.toString(), Object.class);
            collectionNames = (ArrayList<String>) responseMap.get("collections");
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (collectionNames.contains(collectionName)) {
            return;
        }

        String configName = "solr_" + collectionName + "_config";

        try {

            PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = patternResolver.getResources(cfgPath);
            File rourceFile = resources[0].getFile();

            // 上传配置
            String[] args = { "-cmd", "upconfig", "-zkhost", zkHost, "-confdir", rourceFile.getAbsolutePath(), "-confname", configName };
            ZkCLI.main(args);
            // 创建collection
            CollectionAdminRequest.Create collectionCreate = new CollectionAdminRequest.Create();
            collectionCreate.setCollectionName(collectionName);
            collectionCreate.setConfigName(configName);
            collectionCreate.setNumShards(numShards);
            collectionCreate.process(solrClient);
        } catch (Exception e) {
            LOGGER.error("init solr collection error,collectionName:{} , errmsg:{}", collectionName, e.getMessage(), e);
        }

    }

    @Override
    public <T> void addDoc(String id, T doc) {

        SolrInputDocument document = new SolrInputDocument();
        document.addField("id", id);
        try {
            Field field = doc.getClass().getDeclaredField("id");
            field.setAccessible(true);
            field.set(doc, "");
        } catch (Exception e) {
            // ignore
        }
        document.addField("content_sa", gson.toJson(doc));
        try {
            UpdateResponse res = cloudSolrClient.add(document);
            LOGGER.info("solr add object success:{}", res);
            cloudSolrClient.commit();
        } catch (SolrServerException e) {
            LOGGER.error("solr add object error,collection:{} doc:{} , errmsg:{}", collectionName, doc, e.getMessage(), e);
        } catch (Exception e) {
            LOGGER.error("solr add object error,collection:{} doc:{} , errmsg:{}", collectionName, doc, e.getMessage(), e);
        }

    }
Solr初始化代码

3. 封装常用的增删改查代码

  3.1 新增文档:addDoc(String id,T doc);

  3.2 分页查询文档:get(String keyworld, Class<T> claz, Integer start, Integer limit);

  3.3 删除文档:removeDoc(String id);
  3.4 更新文档:updateDoc(String id,T doc);

  

    @Override
    public <T> List<T> get(String keyworld, Class<T> claz, Integer start, Integer limit) {

        List<T> results = new ArrayList<T>();
        try {
            SolrQuery params = new SolrQuery();
            // 设置高亮
            //            params.setHighlight(true).setHighlightSimplePre("<span class='red'>")
            //                    .setHighlightSimplePost("</span>");
            //            query.setParam("hl.fl", "Content");//设置高亮字段
            //            query.setParam("fl", "ID,Published");
            // the common parameters for all search  
            params.set("q", "content_sa:" + keyworld);
            params.set("fl", "id,content_sa"); // field list 返回字段  
            params.set("start", start == null ? "0" : String.valueOf(start)); // 分页  
            params.set("rows", limit == null ? "10" : String.valueOf(limit));

            QueryResponse response = cloudSolrClient.query(params);
            //            System.out.println(params);
            // 查询出来的结果都保存在SolrDocumentList中
            SolrDocumentList res = response.getResults();
            for (SolrDocument document : res) {
                // 打印高亮信息
                LOGGER.debug("solr query result:" + document.get("id").toString() + document.get("content_sa").toString());
                T t = gson.fromJson(document.get("content_sa").toString(), claz);
                try {
                    String id = document.get("id").toString();
                    Field field = claz.getDeclaredField("id");
                    field.setAccessible(true);
                    field.set(t, id);
                } catch (Exception e) {
                    // ignore
                }
                results.add(t);
            }

        } catch (SolrServerException e) {
            LOGGER.error("solr query error, collection :{} , errmsg{}", collectionName, e.getMessage(), e);
        } catch (Exception e) {
            LOGGER.error("solr query error, collection :{} , errmsg{}", collectionName, e.getMessage(), e);
        }

        return results;
    }

    @Override
    public <T> void removeDoc(String id) {

        try {
            cloudSolrClient.deleteById(String.valueOf(id));
            cloudSolrClient.commit();
        } catch (SolrServerException e) {
            LOGGER.error("solr delete error:{}", e.getMessage(), e);
        } catch (Exception e) {
            LOGGER.error("solr delete error:{}", e.getMessage(), e);
        }
    }

    @Override
    public <T> void updateDoc(String id, T doc) {

        addDoc(id, doc);
    }
增删改查代码实现

 

 

需要注意事项:

相关代码请到github上面进行下载:https://github.com/suyin58/spring_solr

需要上传的solr配置(schema配置),已经在test/resource/solr_help_config目录下进行了定义,如果需要对schema的实现进行调整,需要同步调整该目录下的schenma配置

测试使用的test/resource/solr_help_config/managed-schema使用了 IKAnlyzer分词,需要在solr集群中配置IK分词

 

posted @ 2017-03-12 15:52  月·漩涡  阅读(266)  评论(0编辑  收藏  举报

荒淫来到狗窝