solr 多字段查询排序

2 篇文章 0 订阅

最近公司有在用solr作为搜索引擎,然后也了解了一下solr,学习了一些solr相关的知识,并记录下来分享一下。

solr下载地址:

注意:solr8.6之后不支持数据从数据库导入solr中

大家可以看一下solr更新日志:

https://cwiki.apache.org/confluence/display/SOLR/Deprecations

首先是solr的安装:

solr的安装这边不仔细记录一下,基本就是把solr的包放到tomcat下启动,然后放入solr所需要的jar,比如solr,ik,importdata(导入数据)包,然后再创建一个solrHome,创建核心这几个步骤,大家可以自行百度一下哈。

然后创建好索引,我们步入正题结合Spring Boot 使用solr。

首先我们来到solr的admin页面

先介绍一下左边几个比较重要的菜单的作用把

Overview:显示一些统计信息和元数据。

Analysis:帮你设计你的Analyzer,Tokenizer和Filter。

Dataimport: 用于把数据库数据库导入solr,下个文章介绍一下从数据库导入solr

Documents: 提供了一个让你对该Core中的数据作增删改操作的表单窗口。

Files: 不是指存在Core中的业务数据,而是指该Core的配置文件,比如solrconfig.xml。

Query: 对solr进行查询操作(查询,排序,高亮显示等)

Ping: 按一下可以看这个Core还是不是活着的以及响应时间。

Plugins: Solr自带的一些插件以及我们安装的插件的信息以及统计。

Replication:显示你当前Core的副本,并提供disable/enable功能。

Schema: 展示该Core的shema数据,如果是用ManagedSchema模式,还可以通过该页面修改,增加,删除schema的字段。(对比Solr4,是一个比较实用的提升。)

Segments info:展示底层Lucence的分段信息。

 

下面是query页面的相关说明

q查询条件
fq筛选条件
sort排序规则
start,rows分页参数
hl是否高亮显示
hl.fl高亮显示的字段,索引
hl.simple.pre高亮显示的前缀
hl.simple.post高亮显示的后缀
dismax用来修改权重打分
edismax用来修改权重打分

 dismax和edismax都是用来修改权重和打分,但是两则有一些区别

edismax支持boost函数与score相乘作为,而dismax只能使用bf作用效果是相加,所以在处理多个维度排序时,score其实也应该是其中一个维度 ,用相加的方式处理调整麻烦。

具体可参照:https://blog.csdn.net/duck_genuine/article/details/8060026

然后就根据需求来写代码了,哈哈。

首先有以下几个字段:

  • 课程名称
  • 讲师名称
  • 课件名称
  • 发布时间
  • 学分类型

然后用户输入关键字进行查询,要求将关键字进行分词查询,匹配课程,讲师,课件名称,然后将匹配出来的数据进行高亮显示,并按照规则排序显示。

规则如下:

关键字匹配到课程名称的显示上面,然后匹配到讲师名称的显示在其后,配匹到课件名称的显示在最后面。

正常的sort排序肯定满足不了我们的这个需求,所以就用到了dismax

简单介绍以下dismax的参数。

q:  原始输入字符串
q.alt:  调用标准查询解析器并定义q参数为空时候的输入字符串
qf:   查询字段,具体到哪些字段,如果缺省默认为df。例如:qf="course_name^100 expert_name^75 course_ware_name^50" ,后面的数字代表该字段的权重,数字越大,权重越大
mm: 查询最小应该匹配:mm没有定义则在solrconfig.xml中默认指定,默认为100%表示全匹配;mm为正整数指定最小匹配数量;mm为负整数指定匹配最小值减去该值;mm为百分比指定返回该相似性的所有结果;mm为负数百分比,则指定这部分可以忽略;mm为表达式如:3<90%表示:1-3是都需要的,4-是90%需要的
 pf  : phrase fields,使用同qf,主要用于增加匹配文档得分,用于区分相近的查询结果
 ps:  phrase slop,目的是获取确定的短语,ps是pf参数。ps影响增强,如果你用ps值,numFound和结果集不改变。但结果集的顺序改变。
 qs:  Query Phrase Slop: specifies the number of positions two terms can be apart in order to match the specified phrase. Used specifically with the qf parameter.
 tie:  默认为0.0的浮点数<1;
 bq:  boost query  扩展的q参数
 bf :  boost function  例如:recip(rord(myfield),1,2,3)^1.5

 

 

 

 

 

 

我们的需求其实只用q和qf就可以满足。

 

查询结果如下

我们也可以在solr的配置文件中配置,在我们的solrhome中找到这个core下的solrconfig.xml

  <requestHandler name="/select" class="solr.SearchHandler" default="true">
    <lst name="defaults">
		<str name="defType">dismax</str>
       <!-- Change from JSON to XML format (the default prior to Solr 7.0)
          <str name="wt">xml</str> 
         -->
		 <str name="pf">
		courseName expertName courseWareName
		</str>
		<str name="qf">
		courseName^100.0 expertName^50.0 courseWareName^10.0
		</str>
    </lst>
  </requestHandler>

然后重建索引,重启solr就可以了。(每次修改规则需要这样做,比较麻烦)

但最后我们肯定是要用springboot 写的,具体代码如下

public ResposeResultViewModel querySolr(String userId,String courseName,Integer pageIndex,Integer pageSize) throws IOException, SolrServerException {
        ResposeResultViewModel model = new ResposeResultViewModel();
        UserInfoViewModel userInfo = userService.getUserInfoById(userId);
        if(userInfo!=null){
            DataPaginationViewModel dataModel = new DataPaginationViewModel();
            if(pageIndex==null){
                pageIndex=1;
            }
            if(pageSize==null){
                pageSize=10;
            }
            SolrQuery solrQuery = new SolrQuery();
           final Base64.Decoder decoder = Base64.getDecoder();
            courseName = new String(decoder.decode(courseName), "UTF-8");
            solrQuery.setQuery(courseName);
            solrQuery.set("defType","dismax");
            solrQuery.set("qf","course_name^100 expert_name^75 course_ware_name^50");
            //开启高亮显示
            solrQuery.setFilterQueries("organ_id:"+userInfo.getOrgan_id());
            solrQuery.setHighlight(true);
            //设置高亮颜色
            solrQuery.addHighlightField("course_name");
            solrQuery.addHighlightField("expert_name");
            solrQuery.addHighlightField("course_ware_name");
            solrQuery.setHighlightSimplePre("<font color='red'>");
            solrQuery.setHighlightSimplePost("</font>");
            solrQuery.setStart((pageIndex-1)*pageSize);
            solrQuery.setRows(pageIndex*pageSize);
            QueryResponse query = client.query(solrQuery);
            SolrDocumentList results = query.getResults();
            Map<String, Map<String, List<String>>> map = query.getHighlighting();
            results.forEach(res->{
                Map<String, List<String>> listMap = map.get(res.get("course_organ_assign_id"));
                List<String> courseName1 = listMap.get("course_name");
                List<String> courseWareName = listMap.get("course_ware_name");
                List<String> expertName = listMap.get("expert_name");
                res.put("course_name",courseName1==null?res.get("course_name"):courseName1.toString().substring(1,courseName1.toString().length()-1));
                res.put("course_ware_name",courseWareName==null?res.get("course_ware_name"):courseWareName.toString().substring(1,courseWareName.toString().length()-1));
                res.put("expert_name",expertName==null?res.get("expert_name"):expertName.toString().substring(1,expertName.toString().length()-1));
                CourseMarkPojo courseMarkPojo= courseService.getCourseMarkAndStudyUserNumber(res.get("course_id").toString());
                res.put("mark",courseMarkPojo.getMark());
                res.put("study_user_number",courseMarkPojo.getStudy_user_sum());
            });
            long numFound = results.getNumFound();
            dataModel.setTips("查询成功");
            dataModel.setData_list(results);
            dataModel.setData_count((int) numFound);
            dataModel.setData_count(((int)numFound + pageSize - 1)/pageSize);
            model.setCode(0);
            model.setMessage("查询成功");
            model.setBody(dataModel);
        }else{
            model.setCode(1);
            model.setMessage("人员信息为空");
        }

        return model;
    }

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值