搜索引擎solr系列---高亮配置及问题总结

来源:互联网 发布:能看十大禁片的软件 编辑:程序博客网 时间:2024/06/10 10:03

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)@CrossOriginpublic 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内部应该也是这样完成高亮的,因为它至少要匹配一下吧?所以速度没问题。

原创粉丝点击