搜索引擎solr系列---高亮配置及问题总结
2017-10-17 18:16
260 查看
solr的高亮配置有两种方式:
一种是配置形式,具体是在配置文件中配置的,该方式我没有用过,所以我这里就不写它了。另一种就是以代码的形式,我只会用这种方式,所以只写这部分。
其实还要一种就是自我实现,这个更简单粗暴。
1.高亮的代码具体如下:
package cloud.solr.controller; import cloud.solr.controller.base.BaseController; import cloud.solr.domain.Fbf; import org.apache.commons.lang3.math.NumberUtils; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.StringUtils; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by lsf on 2017/10/17. */ @RestController @RequestMapping("/test") public class TestController extends BaseController { @RequestMapping(value = "/select",method = RequestMethod.GET) @CrossOrigin public Object getById(HttpServletRequest request) { /** * http://192.168.1.170:8983/solr/fbf fbf是solr的一个core名称 */ long start = System.currentTimeMillis(); HttpSolrClient solrClient = new HttpSolrClient("http://192.168.1.170:8983/solr/fbf"); SolrQuery query = new SolrQuery(); query.setSort("createtime",SolrQuery.ORDER.asc); //设置排序 String pageNo = request.getParameter("pageNo"); //第几页 String pageSize = request.getParameter("pageSize"); ; //每页多少数据 if(NumberUtils.isNumber(pageNo) && NumberUtils.isNumber(pageSize)){ int startPage = Integer.valueOf(pageNo); int pageNum = Integer.valueOf(pageSize); query.setStart((startPage-1)*pageNum);//起始页,这里一定要注意,不能直接把pageNo赋值给start。 query.setRows(pageNum);//每页显示数量 } query.setHighlight(true);// 开启高亮组件 query.setHighlightRequireFieldMatch(true); query.set("hl.fl","fbfmc"); // 高亮的第一种写法字段 // query.addHighlightField("fbfmc"); //高亮的第一种写法 query.setHighlightSimplePre("<font color='red'>"); //高亮的标签前缀 query.setHighlightSimplePost("</font>");//高亮的标签后缀 query.setHighlightFragsize(150); String fbfmc = request.getParameter("fbfmc"); query.addHighlightField("fbfbm"); // 高亮字段 StringBuffer buffer = new StringBuffer(); /**第一种查询写法**/ if(!StringUtils.isEmpty(fbfmc)){ buffer.append("fbfmc:"+fbfmc); query.set("q",buffer.toString()); }else{ query.set("q","*:*"); } /**第一种查询写法**/ /**第二种查询写法,但是这种查询方式,我配置高亮时失败了,用第一种查询是可以的**/ // query.set("q","*:*"); // if(!StringUtils.isEmpty(fbfmc)){ // query.addFilterQuery("fbfmc:" +fbfmc); // } /**第二种查询写法**/ QueryResponse rsp = null; try { rsp = solrClient.query( query ); } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //获取所有高亮的字段 SolrDocumentList results = rsp.getResults(); Map<String,Map<String,List<String>>> highlightresult=rsp.getHighlighting(); System.out.println(results.getNumFound());//查询总条数 List<Fbf> fbfList = rsp.getBeans(Fbf.class); for(int i=0;i<fbfList.size();i++){ String poid = fbfList.get(i).getPoid(); if (highlightresult.get(poid) != null){ //如果查询结果的fbfmc在高亮map中有结果则进行替换。 if(highlightresult.get(poid).get("fbfmc") != null){ fbfList.get(i).setFbfmc(highlightresult.get(poid).get("fbfmc").get(0)); } } } Map result = new HashMap<String,Object>(); result.put("totalNum",results.getNumFound()); result.put("fbfList",fbfList); long end = System.currentTimeMillis(); System.out.println("Fbf查询消耗时间:"+(end-start)+"ms"); return result; } }
2.高亮遇到的问题:
(1)query.addFilterQuery(“fbfmc:” +fbfmc)查询条件添加和query.addHighlightField(“fbfmc”)高亮字段添加,以这种写法,高亮配置失败。
这个我不知道其他人是如何配置的,反正我一这么写就失败,暂且认为是这个原因吧,我的解决方式是,查询条件改成`query.set(“q”,”fbfmc:”+fbfmc)写法;
(还记得这里的fbfmc如果manage-schema文件中fbfmc是text_ik类型时可以这么写,如果是string则需要在两边加上*)
高亮字段设置改成
query.set("hl.fl","fbfmc")写法(多个字段以逗号隔开);将这两个地方改成后者,即可配置高亮成功。具体可以先在solr客户端上验证成功再写在代码里。
(2)如果你要设置的高亮字段是string类型,不是text_ik类型,那么在查询时,你肯定会传入模糊查询符号*,这样查询到结果高亮后,会将该字段全部匹配,比如传入的是0115,结果中是100115符合该查询,那么整个100115会被高亮,因为它是根据你的分词来进行高亮的。所以我感觉高亮并不适合string类型的。如果要想模糊查询又达到高亮,需要自己写,具体看最后。
(3)高亮对于数字定义成text_ik这种类型,好像可以从前匹配,但是从中间或从最后就无法匹配成功,比如:633330222111,如果输入63333有可能匹配成功,但是输入0222,或者输入1111是无法匹配成功的。
(4)高亮的显示结果,会按照匹配的频率最高的,放到最前边展示,如果以相邻距离最近设置,这个我不会,我也好想知道如何配置。
3.自定义高亮:
具体场景是,我们领导要求如果输入一个没有空格的字符串则是模糊查询,如果输入俩字符串中间以空格隔开,则相当于是两个条件,这两个就全都匹配下该字段。这种情况的解决是我将所有的字段都定义为string类型,不适用text_ik,将传入的条件写成
query.set("q","fbfmc:*"+fbfmc+“*”)这种写法,如果是以空格,则后台判断后,进行一次拼接,比如俩条件,那就写成
query.set("q","fbfmc:*"+fbfmc+"* OR fbfmc:*"+fbfmc2+"*"),注意中间的OR或者AND必须用大写
因为这种场景高亮是无法精确高亮了,所以,我就将查询结果拿到之后,遍历结果,然后匹配fbfmc字段,如果符合则给添加一个标签,
for(Fbf fbf:fbfList){ if(qwppArray != null){ for(String qwppStr:qwppArray){ if(!StringUtils.isEmpty(fbf.getFbfmc())) fbf.setFbfmc(fbf.getFbfmc().replace(qwppStr,"<font color='red'>"+qwppStr+"</font>")); } } }
然后再将对象返回,返回结果再加上分页,效率并不影响,还是一样快,其实我觉得solr内部应该也是这样完成高亮的,因为它至少要匹配一下吧?所以速度没问题。
相关文章推荐
- 关于在ECLIPSE中配置weblogic的问题总结:
- 解决过滤王不刷卡上机网络配置问题(总结篇)
- 算法总结系列之七:选择问题(Randomized Select)
- [导入]算法总结系列之七:选择问题(Randomized Select)
- windows下php5 apache2.2 mysql5 配置中的问题总结
- 【Hibernate总结系列】....hbm.xml配置
- 学习ejb并配置一个简单的helloEjb是遇到问题后总结的经验。
- AD子域DNS服务器配置的几点问题总结
- NS系列防火墙常见问题总结(有问题的朋友先到这里看看)
- Struts1.x系列教程(24):配置文件总结
- failed to open stream解决办法-关于WIN主机下配置PHP的若干问题解决方案总结
- 网店版重生系列:Linux下Jboss启动、关闭、端口配置等常见问题FAQ
- 字符集本地化(locale)与输入法系列讲座-----(4) Ubuntu Locale配置问题根源解决之道
- nagios配置常见问题的总结
- ASP.NET与IIS配置问题总结!
- Struts1.x系列教程(24):配置文件总结
- ASP.NET与IIS配置问题总结!
- AD子域DNS服务器配置的几点问题总结
- ASP.NET与IIS配置问题总结!
- 【Struts1.2总结系列】validation.xml验证文件的配置