搜索引擎-基于solrj客户端的solr增删改查 (附:大神博客链接)

solr搜索技术帖:
http://blog.csdn.net/hu948162999/article/category/2582709

Solrj已经是很强大的solr客户端了。以完全对象的方式对solr进行交互。很小很好很强大。最基本的功能就是管理Solr索引,包括添加、更新、删除和查询等。

在此之前:先介绍一个异常,以前有朋友问过这个,最近查了下solrj的源码。

2014-10-16 17:52:07,486 ERROR [org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer] -
org.apache.solr.common.SolrException: Not Found

或者 org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException: Expected mime type application/xml but got text/html

这是报错的solrj部分源代码

method = new HttpPost(server.getBaseURL() + “/update”
+ ClientUtils.toQueryString(requestParams, false));–注意这里路径getBaseURL

int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
StringBuilder msg = new StringBuilder();
msg.append(response.getStatusLine().getReasonPhrase()); —–这里NOT FOUND
msg.append(“\n\n”);
msg.append(“\n\n”);
msg.append(“request: “).append(method.getURI());
handleError(new SolrException(ErrorCode.getErrorCode(statusCode), msg.toString())); –执向这一行异常,并且打印msg,这里打印确实有点坑
} else {
onSuccess(response);
}

通过其端点跟踪 ,不难发现是由于URL拼接而成的路径报错,也就是说服务器的请求路径不对。一般是服务器后面跟踪的core的不对,所导致整个请求路径不对

老习惯:直接代码分析

    package com.hhc.searchEngine;  

    import org.apache.log4j.Logger;  
    import org.apache.solr.client.solrj.SolrQuery;  
    import org.apache.solr.client.solrj.SolrServer;  
    import org.apache.solr.client.solrj.SolrServerException;  
    import org.apache.solr.client.solrj.response.QueryResponse;  
    import org.apache.solr.client.solrj.response.UpdateResponse;  
    import org.apache.solr.common.SolrDocument;  
    import org.apache.solr.common.SolrDocumentList;  
    import org.apache.solr.common.SolrInputDocument;  
    import org.springframework.beans.BeanUtils;  
    import org.springframework.web.servlet.ModelAndView;  

    import com.ws.cache.model.FieldInfo;  
    import com.ws.cache.model.Scheme;  
    import com.ws.utils.SearchInitException;  
    import com.ws.utils.StringUtils;  
    import com.ws.utils.converter.ConverterUtils;  

    import freemarker.template.TemplateException;  

    import java.io.IOException;  
    import java.net.MalformedURLException;  
    import java.sql.Clob;  
    import java.util.*;  
    import java.util.Map.Entry;  

    import javax.servlet.http.HttpServletRequest;  

    /** 
     * 基于solr实现的搜索引擎. 
     *  
     * @author huhuichao ([email protected]) 
     * @version V1.0 
     * @createTime 2014-10-13 
     */  
    @SuppressWarnings("unchecked")  
    public class SearchEngine {  

        private static final Logger logger = Logger.getLogger(SearchEngine.class);  

        private String server = "http://localhost:8080/solr";  

        private SolrServer solrServer = null;  

        private SolrServer getSolrServer(Scheme scheme) throws SearchInitException {  

            try {  
                solrServer = scheme.getConcurrentUpdateSolrServer();  
            } catch (Exception e) {  
                e.printStackTrace();  
                logger.error("null solr server path! !");  
                throw new SearchInitException(  
                        "null solr server path! !");  
            }  
            return solrServer;  

        }  

        /** 
         * 根据数据模型 
         * 增加维护索引 
         * @param scheme  --索引方案 
         * @param list  --数据模型 
         * @throws Exception 
         */  
        public synchronized void AddSearchIndex(Scheme scheme,List> list)  
                throws Exception {  
            SolrServer solrServer = getSolrServer(scheme);  
            //用来存储数据文档  
            List lstDocument=new ArrayList();  

            SolrInputDocument document=null;  
            for(Map map:list){  
                //map.remove("RN");  
                //构造数据模型  
                document=new SolrInputDocument();  
                /* 
                 * 先数据自定义处理,然后把处理的数据创建相应的索引 
                 */  
                for(Entry ety:map.entrySet()){  
                    for(FieldInfo fieldInfo:scheme.getFiledInfos()){  
                        if(ety.getKey().toString().equals(fieldInfo.getFieldcode())){  
                            //取得数据库中字段的值,分析其在数据库中的类型  
                            Object obj=ety.getValue();   

                            //对CLOB字段的处理  
                            if(obj instanceof Clob){  
                                //对这种格式的文本转化成String类型  
                                obj = ConverterUtils.clobToStr((Clob)obj);  
                            }  
                            //防止分词器出现异常。  
                            //对特殊字符处理  
                            if(obj!=null){  
                                obj = obj.toString().trim().replaceAll("\'", "”");  
                                obj = obj.toString().replaceAll("\"", "”");   
                            }  

                            // 保证每个对象的唯一性,而且通过对象的主键可以明确的找到这个对象在solr中的索引  
                            if(scheme.getPkfield().equalsIgnoreCase(fieldInfo.getFieldcode())){  
                                 document.addField("primary_key", obj);//主键  
                                 document.addField("schecode", scheme.getCode().toLowerCase());//方案code   
                            }else{  
                                document.addField(ety.getKey().toLowerCase(), obj);//ent.getValue()  
                                if(scheme.getInsertsjcfield().equalsIgnoreCase(fieldInfo.getFieldcode())){  
                                     document.addField("insertsj", obj);//插入时间戳  
                                 }    
                                if(scheme.getUpdatesjcfield().equalsIgnoreCase(fieldInfo.getFieldcode())){  
                                     document.addField("updatesj", obj);//更新时间戳  
                                 }  
                            }  
                        }                 
                    }  
                }  
                lstDocument.add(document);  
            }  
            solrServer.add(lstDocument);  
            solrServer.commit();              
        }  

        /** 
         * 删除单个solr文本节点--通过文档id 
         * @param bean 
         * @throws Exception 
         */  
        public synchronized void deleteIndex(String id,Scheme scheme) throws Exception {  
            if (scheme == null) {  
                logger.warn("Get search bean is empty!");  
                return;  
            }  
            SolrServer server = getSolrServer(scheme);  
            server.deleteById(id);  
            server.commit();  
        }  

        /** 
         * 删除多个个solr文本节点--通过文档id集 
         * @param list--(id的集合) 
         * @throws Exception 
         */  
        @SuppressWarnings("unchecked")  
        public synchronized void deleteIndexs(List list,Scheme scheme)  
                throws Exception {  
            if (scheme == null) {  
                logger.warn("Get search bean is empty!");  
                return;  
            }  
            SolrServer server = getSolrServer(scheme);  
            server.deleteById(list);  
            server.commit();  
        }  


            /** 
             * solr查询 
             * @param request 
             * @return 
             */  
            public ModelAndView solrSearch (HttpServletRequest request){  
                ModelAndView mav = new ModelAndView("/huhuichao/solr/test.jsp");  
                Map map = super.getParamValues(request);  
                //获取拼接好的查询参数  
                String pueryParams=getQueryParams(map);  

                map = super.pageXX(map, request);  

                //创建远程服务--调用方案  
                SolrServer httpSolrServer = getSolrServer((Scheme)map.get("scheme"));         
                //设置查询参数  
                SolrQuery params=new SolrQuery();  
                params.setParam("q", pueryParams);  
                //设置查询展示字段-- *,score 的话 查询所有字段。。会很慢。  
                //params.setParam("fl","c495,c505,c639,c610,c554,c555,c502,score");  
                //返回结果集。。全文检索从第0页开始   +1  
                params.setStart((Integer.parseInt(map.get((将字符串转换成整数)"page").toString())-1)*10);  
                params.setRows(10);  
                //设置排序字段  
                params.setSortField("c610", SolrQuery.ORDER.desc);  
                //执行查询-返回结果集  
                try {  
                    QueryResponse reponse = httpSolrServer.query(params);     
                    List list=reponse.getResults();  
                    //组装pager对象  
                    Pager pager=new Pager((int)reponse.getResults().getNumFound(), 10, Integer.parseInt((将字符串转换成整数)map.get("page").toString()));  
                    //System.out.println(reponse.getResults());  
    //              for (SolrDocument result : reponse.getResults()) {  
    //                  System.out.println(result);  
    //              }     
                    pager.setResults(list);  
                    mav.addObject("pager", pager);  
                } catch (SolrServerException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }                     
                //Pager pager = this.wscbajManager.wscbajQuery(map);  
                mav.addObject("map", map);  
                return mav;  
            }  



        /** 
         * 通过索引类型删除索引 
         * @param indexType 
         * @param scheme 
         * @throws Exception 
         */  
        public synchronized void deleteIndexsByIndexType(String indexType,Scheme scheme)  
                throws Exception {  
            SolrServer server = getSolrServer(scheme);  
            UpdateResponse ur = server.deleteByQuery("indexType:" + indexType);  
            server.commit();  
        }  

        /** 
         * 清空索引 
         * @param scheme 
         * @throws Exception 
         */  
        public synchronized void deleteAllIndexs(Scheme scheme) throws Exception {  
            SolrServer server = getSolrServer(scheme);  
            UpdateResponse ur = server.deleteByQuery("*:*");  
            server.commit();  
        }  


        /** 
         * 更新索引
* 在solr中更新索引也就是创建索引(当有相同ID存在的时候,会覆盖上一个索引节点,否则新建)
* {@link SolrSearchEngine#doIndex(java.util.List)} * * @param Schemes * 需要更新的方案 * @throws Exception */
public void updateIndexs(Scheme scheme,List> list) throws Exception { this.AddSearchIndex(scheme,list); } }

通过url获取solr服务器的时候。注意在solr4.0后 CommonsHttpSolrServer 这个类已经被 HttpSolrServer取代了

在solrj中 提出了3种常用的删除操作对外接口
这是从其源码中拷贝出来的删除代码
  /**
   * Deletes a single document by unique ID
   * @param id  the ID of the document to delete
   * @throws IOException If there is a low-level I/O error.
   */
  public UpdateResponse deleteById(String id) throws SolrServerException, IOException {
    return deleteById(id, -1);
  }


  /**
   * Deletes a list of documents by unique ID
   * @param ids  the list of document IDs to delete 
   * @throws IOException If there is a low-level I/O error.
   */
  public UpdateResponse deleteById(List ids) throws SolrServerException, IOException {
    return deleteById(ids, -1);
  }


   /**
   * Deletes documents from the index based on a query
   * @param query  the query expressing what documents to delete
   * @throws IOException If there is a low-level I/O error.
   */
  public UpdateResponse deleteByQuery(String query) throws SolrServerException, IOException {
    return deleteByQuery(query, -1);
  }


  //从这段代码 可以看出,就是循环删除单个文本节点操作
  public UpdateRequest deleteById(List ids) {
    if (deleteById == null) {
      deleteById = new LinkedHashMap<>();
    }

    for (String id : ids) {
      deleteById.put(id, null);
    }

    return this;
  }


}

solr 搜索技术帖:
http://blog.csdn.net/hu948162999/article/category/2582709

你可能感兴趣的:(搜索)