Java 操作Solr搭建高性能搜索引擎

转自:https://blog.csdn.net/wmq880204/article/details/78421726

 目前比较适合Java的搜索引擎搭建一般会选用Solr,底层操作会使用Solrj交互,其实Solr也是基于Lucene。实施过程中发现网上很多关于Java集成Solr的文档都是基于Solr5+版本的,而对于Solr7+版本的文档很少,并且很多都是坑,所以花了不少时间把自己再部署过程中的经验分享出来。

      首先去官网 Apache Solr官网  下载Solr的7.1,然后上传至服务器,在bin目录下面有个执行文件,通过命令/bin/solr start -force 可以很方便的启动Solr7。

  接下去开始Solr的相关配置:

      1.在solr中新建一个项目,在bin目录下使用solr create -C '库名'

      2.编辑managed-schema配置文件,加入IK分词器,这个分词器对中文支持较好
   
   
   
   

 3.配置managed-schema加入字段的通配设置,
       使用这种通配方式配置后,你的程序代码Model中的属性字段可以写成XXX_ikBookStr等即可被Solr识别添加至索引,在查询时也能够使用此字段。
     4.将第一步创建的SolrCore copy到Solr根目录下面,此时访问你的Solr网站即可看到你的SolrCore

        

    5.至此Solr服务端已经搭建完成了,接下去要在程序里面进行编码,首先在pom.xml中引入Solr包支持

    6.然后再model的属性字段set方法上面加上@Field注解,这个注解是用来告诉Solr此字段需要被添加至索引中,但是值得注意的是此字段命名必须符合上面的通配设置规范

  7.接下去就是SpringBoot对于Solr的封装操作了,我是再次做了一次封装便捷实用,贴出我的代码

public class SolrRepository {
    @Autowired
    private SolrClient client;
    private QueryResponse response;
    private SolrDocumentList results;
 
    /**
     * 
     * 
       TODO - 针对Solr进行数据查询
       @param query 查询关键字
       @param offset 起始位置
       @param limit 每次查询条数
       @param c 实体类对象
       @param bool 是否关闭Solr链接
       @param qf 搜索关键字匹配某些字段的打分比其他的字段要高
       @param pf 对于某些字段,搜索字符串的密集度(phrase)的打分中占的比重
       @param fl 指定需要返回的字段 逗号分隔
       @param fq 指定过滤条件
       @return
       @throws Exception
       2017年10月3日
       mazkc
     */
    public List getSolrData(String query,String offset,String limit,String c,Boolean bool,String qf,String pf,String solrFl,String fq) throws Exception {
        ModifiableSolrParams params = new ModifiableSolrParams();
        List beans = null;
        //如果limit为空 或者 超过限定抓取数量 那么返回null
        if(null == limit || "".equals(limit) || Integer.parseInt(limit) > FinalArgs.SERACH_LIMIT){
            return null;
        }
        params.set("q", query);
        params.set("wt", "json");
        params.set("start", "0");
        params.set("rows", "10");
        params = checkNotNull(params,offset,limit,qf,pf,solrFl,fq);
        response = client.query(params);
        if(null == c || "".equals(c)){
            beans = response.getResults();
        }else{
            beans = response.getBeans(Class.forName(c));
            if(null == beans || beans.size() == 0){
                beans = new ArrayList<>();
                beans.add(Class.forName(c).newInstance());
            }
        }
        commitAndCloseSolr(client,bool);
        return beans;
    }
    
    /**
     * 
     * 
       TODO - 验证Solr查询是否有优化
       @param params 参数关键字
       @param offset 起始位置
       @param limit 请求数据条数
       @param qf 匹配权重
       @param pf 出现字数权重
       @param solrFl 需要返回的字段
       @param fq 过滤哪些数据
       @return
       2017年10月17日
       mazkc
     */
    private ModifiableSolrParams checkNotNull(ModifiableSolrParams params,String offset,String limit,String qf,String pf,String solrFl,String fq){
        if(null != offset && !"".equals(offset)){
            params.set("start", offset);
        }
        if(null != limit && !"".equals(limit)){
            if(Integer.parseInt(limit) >= 200){
                limit = "200";
            }
            params.set("rows", limit);
        }
        if(null != qf && !"".equals(qf)){
            params.set("qf", qf);
        }
        if(null != pf && !"".equals(pf)){
            params.set("pf", pf);
        }
        if(null != solrFl && !"".equals(solrFl)){
            params.set("fl", solrFl);
        }
        if(null != fq && !"".equals(fq)){
            params.set("fq", fq);
        }
        params.set("defType", "edismax");
        return params;
    }
    
    /**
     * 
     * 
       TODO - 针对集合数据对Solr进行数据索引
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void saveSolrDataList(List li,Boolean bool) throws Exception {
        if(null != li && li.size() > 0){
            client.addBeans(li);
            commitAndCloseSolr(client,bool);
        }
    }
    
    /**
     * 
     * 
       TODO - 根据索引ID查询solr数据
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public SolrDocument getSolrDataById(String id,Boolean bool) throws Exception {
        SolrDocument so = client.getById(id);
        commitAndCloseSolr(client,bool);
        return so;
    }
    
    /**
     * 
     * 
       TODO - 针对单个数据对Solr进行数据索引
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void saveSolrData(Object bean,Boolean bool) throws Exception {
        if(null != bean){
            client.addBean(bean);
            commitAndCloseSolr(client,bool);
        }
    }
    
    /**
     * 
     * 
       TODO - 根据集合删除所有索引文档
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void delSolrDataList(List li,Boolean bool) throws Exception {
        if(null != li && li.size() > 0){
            client.deleteById(li);
            commitAndCloseSolr(client,bool);
        }
    }
    
    /**
     * 
     * 
       TODO - 批量删除所有索引文档
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void delSolrDataAll(String query,Boolean bool) throws Exception {
        client.deleteByQuery(query);
        commitAndCloseSolr(client,bool);
    }
    
    /**
     * 
     * 
       TODO - 根据ID删除所有索引文档
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void delSolrDataId(String id,Boolean bool) throws Exception {
        client.deleteById(id);
        commitAndCloseSolr(client,bool);
    }
    
    /**
     * 
     * 
       TODO - 根据索引ID更新索引数据
       @param map
       @throws Exception
       2017年10月2日
       mazkc
     */
    public void updateSolrData(String queryId,HashMap map,Boolean bool) throws Exception {
        SolrInputDocument doc = new SolrInputDocument(); 
        SolrDocument sd = getSolrDataById(queryId, false);
        Iterator it = sd.keySet().iterator();
        String key = "";
        //获取所有源数据信息
        while(it.hasNext()){
            key = it.next();
            doc.addField(key, sd.getFieldValue(key));
        }
        Iterator itt = map.keySet().iterator();
        //将需要更新的数据补充进源数据
        while(itt.hasNext()){
            key = itt.next();
            doc.remove(key);
            doc.addField(key, map.get(key));
        }
        client.add(doc);
        commitAndCloseSolr(client,bool);
    }
    
    private SolrInputDocument checkDoc(HashMap map,SolrInputDocument doc){
        if(null != map && null != doc){
            String key = "";
            Iterator it = map.keySet().iterator();
            while(it.hasNext()){
                key = it.next();
                doc.addField(key, map.get(key));
            }
        }
        return doc;
    }
    
    /**
     * 提交以及关闭服务
     * 
     * @param solrClient
     * @throws Exception
     */
    public void commitAndCloseSolr(SolrClient client,Boolean bool)
            throws Exception {
        if(null != client){
            client.commit();
//            if(bool){
//                client.close();
//            }
        }
    }
}
 

你可能感兴趣的:(开发)