搜索引擎-基于solrj客户端的solr增删改查
2014-10-13 21:19
951 查看
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的不对,所导致整个请求路径不对
老习惯:直接代码分析
通过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;
}
}
在此之前:先介绍一个异常,以前有朋友问过这个,最近查了下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页开始 +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<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 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(); } /** * 更新索引<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;
}
}
相关文章推荐
- 搜索引擎-基于solrj客户端的solr增删改查 (附:大神博客链接)
- 企业级搜索应用服务器Solr4.10.4部署开发详解(3)- Solr使用-使用java客户端solrj进行增删改查开发
- 基于Lucene的Solr服务搜索引擎应用(散乱)
- Solr客户端 SolrJ单机 添加查询操作
- solr 的客户端调用solrj 建索引+分页查询
- solrJ的增删改查,solrDocument与Bean的映射,直接增删该查bean完成对索引的操作
- 全文索引----solr客户端工具solrJ
- solr 的客户端调用solrj 建索引+分页查询
- 基于hadoop+nutch+solr的搜索引擎环境搭载<一>hadoop完全分布式环境搭建
- solr学习第六课---solr中facet的基本应用-基于solr搜索引擎
- solr 的客户端调用solrj 建索引+分页查询
- Solr JAVA客户端SolrJ 4.9使用示例教程
- 全文搜索服务器solr之客户端 - solrj二次开发
- 三.使用solrj5客户端对solr服务进行增删查
- solr学习第七课----solr之数据库数据导入生成索引(DataImportHandler)-基于solr搜索引擎
- 【开源】基于C/S架构的Android员工增删改查客户端
- 基于apache lucene的solr站内搜索引擎搭配手记之2
- solr学习笔记 -- day03 使用solrJ客户端
- [solr] - SolrJ增删查
- [solr] - SolrJ增删查