搜索引擎-基于solrj客户端的solr增删改查

来源:互联网 发布:欧陆风云4 for mac 编辑:程序博客网 时间:2024/05/29 11:15

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

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

2014-10-16 17:52:07,486 ERROR [org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer] - <error>
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 (huhc3@asiainfo.com) * @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<Map<String, Object>> list)throws Exception {SolrServer solrServer = getSolrServer(scheme);//用来存储数据文档List<SolrInputDocument> lstDocument=new ArrayList<SolrInputDocument>();SolrInputDocument document=null;for(Map<String,Object> map:list){//map.remove("RN");//构造数据模型document=new SolrInputDocument();/* * 先数据自定义处理,然后把处理的数据创建相应的索引 */for(Entry<String, Object> 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页开始   +1params.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<T> pager=new Pager<T>((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 blocke.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();}/** * 更新索引<br/> * 在solr中更新索引也就是创建索引(当有相同ID存在的时候,会覆盖上一个索引节点,否则新建)<br/> * {@link SolrSearchEngine#doIndex(java.util.List)} *  * @param Schemes *            需要更新的方案 * @throws Exception */public void updateIndexs(Scheme scheme,List<Map<String, Object>> 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<String> 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<String> ids) {
    if (deleteById == null) {
      deleteById = new LinkedHashMap<>();
    }
    
    for (String id : ids) {
      deleteById.put(id, null);
    }
    
    return this;
  }



}

1 0
原创粉丝点击