当前位置: 首页 > article >正文

集成solr复盘

公司有个平台要在微服务中集成搜索引擎,选了solr,第一次研究搜索引擎,记录一下集成过程

在csdn上找了一篇教程:springboot集成solr实现全局搜索系列,作者写的很详细

环境

jdk:jdk1.8.0_51

Solr:solr-8.11.2

tomcat:tomcat 8

微服务框架:ruoyi-cloud-2.4.0

项目相关文件git地址:https://gitee.com/lmr-replay/replay-solr

安装并配置solr

这里基本都是参照教程安装的,不会安装的小伙伴可以看一下上面的教程,很详细

springboot集成solr

这块我选择作为一个单独的服务集成到微服务中,方便后期其他项目引入

因为跟数据库做的定时同步,这块只实现了查询方法

core:article_core、business_core、recruit_core、course_core

每个core第一的字段都相同:id、title、content、author、keywords

  1. 首先引入mave

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-solr</artifactId>
    </dependency>
    
  2. 在nacos中配置solr服务端地址

    spring:data:solr:host: http://localhost:8090/solr/
    
  3. 创建solr获取的数据对象实体类

    项目这块的需求是要同时查询多个表的数据,表之间没有关联,这块想了好久,不知道是要定义一个core来处理还是应该创建多个core来处理

    首先配置了一个core来处理多个表的数据,有很多问题,处理起来太麻烦,这块因为催的比较紧急,选择了每个表创建一个core

    这块有大神知道这个问题怎么解决的,有时间的话麻烦私聊指教一下,🙏🙏🙏

    • 创建单个Core对象:CoreParam

      public class CoreParam {/** 查询的core */private String core;/** 默认查询字段 */private String dfFiled;/** 排序(id desc,name asc) */private String sort;public String getCore() {return core;}public void setCore(String core) {this.core = core;}public String getDfFiled() {return dfFiled;}public void setDfFiled(String dfFiled) {this.dfFiled = dfFiled;}public String getSort() {return sort;}public void setSort(String sort) {this.sort = sort;}
      }
      
    • 创建Solr查询参数对象:SolrSearchParam

      public class SolrSearchParam {/** 索引 */private String id;/** 用户输入的查询字符串 */private String q;/** 分页定义结果起始记录数 */private Integer start;/** 分页定义结果每页返回记录数 */private Integer rows;/*** 需要检索的core列表*/private List<CoreParam> coreParams;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getQ() {return q;}public void setQ(String q) {this.q = q;}public Integer getStart() {return start;}public void setStart(Integer start) {this.start = start;}public Integer getRows() {return rows;}public void setRows(Integer rows) {this.rows = rows;}public List<CoreParam> getCoreParams() {return coreParams;}public void setCoreParams(List<CoreParam> coreParams) {this.coreParams = coreParams;}
      }
      
    • Solr分页数据返回类:SolrDataInfo

      public class SolrDataInfo implements Serializable {private static final long serialVersionUID = 1L;private long total;private List<?> rows;private int code;private String msg;private String title; // 标题private String authorTitle; // 作者字段标题public String getAuthorTitle() {return authorTitle;}public void setAuthorTitle(String authorTitle) {this.authorTitle = authorTitle;}public long getTotal() {return total;}public void setTotal(long total) {this.total = total;}public List<?> getRows() {return rows;}public void setRows(List<?> rows) {this.rows = rows;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}
      }
      
  4. 创建SolrCore枚举

    定义页面上显示的数据类型、参数名称及详情页url

    /*** SolrCore枚举*/
    public enum SolrCoreEnum {ARTICLE_CORE("article_core","/articleDetail?id=#{id}","资讯", "作者"),BUSINESS_CORE("business_core", "/companyDetail/?id=#{id}", "企业", "行业"),RECRUIT_CORE("recruit_core", "/recruitDetail?id=#{id}", "招聘信息", ""),COURSE_CORE("course_core", "/courseDetail/?courseId=#{id}", "就业课程", "课程类型");private String core; // Solr Coreprivate String detailUrl; // 详情页链接(使用#{id}注明id拼接位置)private String title; // 标题private String authorTitle; // 作者字段标题public static String getDetailUrl(String core, Long id) {for (SolrCoreEnum solrCore : SolrCoreEnum.values()) {if (solrCore.getCore().equals(core)) {if (StringUtils.isNotNull(id)) {solrCore.detailUrl = solrCore.detailUrl.replaceAll("\\#\\{id\\}", String.valueOf(id));}return solrCore.detailUrl;}}return "";}public static String getTitle(String core) {for (SolrCoreEnum solrCore : SolrCoreEnum.values()) {if (solrCore.getCore().equals(core)) {return solrCore.title;}}return "";}public static String getAuthorTitle(String core) {for (SolrCoreEnum solrCore : SolrCoreEnum.values()) {if (solrCore.getCore().equals(core)) {return solrCore.authorTitle;}}return "";}public String getCore() {return core;}SolrCoreEnum() {}SolrCoreEnum(String core, String detailUrl, String title, String authorTitle) {this.core = core;this.detailUrl = detailUrl;this.title = title;this.authorTitle = authorTitle;}
    }
    
  5. 创建Solr查询Service

    /*** @ClassName SolrSearchParam* @Author lmr* <p>* SolrService* <p>* @Date 2022/8/12 0012 16:34* @Version 1.0**/
    public interface SolrService {/*** 查询* @param param* @return* @throws IOException* @throws SolrServerException*/AjaxResult querySolr(SolrSearchParam param) throws IOException, SolrServerException;
    }
    
  6. 创建Solr查询Service实现

    @Service
    public class SolrServiceImpl implements SolrService {@Autowiredprivate SolrClient client;/*** 高亮查询*/@Overridepublic AjaxResult querySolr(SolrSearchParam param) throws IOException, SolrServerException {HashMap<String, Object> map = new HashMap<>();// 获取所有需要查询的coreList<CoreParam> coreParams = param.getCoreParams();// 查询到的记录总行数Long total = 0L;for (CoreParam core : coreParams) {SolrDocumentList solrDocuments;if (StringUtils.isNull(param.getStart())) {solrDocuments = querySolr(core.getCore(), param.getQ(), core.getDfFiled(), core.getSort());} else {solrDocuments = querySolr(core.getCore(), param.getQ(), core.getDfFiled(), core.getSort(), param.getStart(), param.getRows());}for (SolrDocument solrDocument : solrDocuments) {// 从枚举中获取详情页url并拼装idsolrDocument.setField("detailUrl", SolrCoreEnum.getDetailUrl(core.getCore(),Long.parseLong(solrDocument.getFieldValue("id").toString())));}// 组装分页数据SolrDataInfo rspData = new SolrDataInfo();rspData.setRows(solrDocuments);rspData.setMsg("查询成功");long numFound = solrDocuments.getNumFound();total += numFound;// 单类型记录数rspData.setTotal(numFound);rspData.setTitle(SolrCoreEnum.getTitle(core.getCore()));rspData.setAuthorTitle(SolrCoreEnum.getAuthorTitle(core.getCore()));// 以core作为key返回数据map.put(core.getCore(), rspData);}map.put("total", total);return AjaxResult.success(map);}/*** 查询* @param core 要查询的core* @param q 用户输入的字符串* @param dfField 默认的查询字段* @param sort 排序字段* @return* @throws IOException* @throws SolrServerException*/public SolrDocumentList querySolr(String core, String q, String dfField, String sort) throws IOException, SolrServerException {return querySolr(core, q, dfField, sort, 0, 10);}/*** 查询* @param core 要查询的core* @param q 用户输入的字符串* @param dfField 默认的查询字段* @param sort 排序字段* @param start 分页定义结果起始记录数* @param rows 分页定义结果每页返回记录数* @return* @throws IOException* @throws SolrServerException*/public SolrDocumentList querySolr(String core, String q, String dfField, String sort, Integer start, Integer rows) throws IOException, SolrServerException {SolrQuery params = new SolrQuery();//查询条件, 这里的 q 对应 下面图片标红的地方params.set("q", q);// 过滤条件// params.set("fq", "product_price:[100 TO 100000]");// 组装排序if (!StringUtils.isEmpty(sort)) {// 多个字段使用,分开String[] sorts = sort.split(",");for (String sortItem : sorts) {// 字段和排序方式使用' '分开String[] items = sortItem.split(" ");if (items.length > 1) {params.addSort(new SolrQuery.SortClause(items[0], items[1]));} else {params.addSort(new SolrQuery.SortClause(items[0], SolrQuery.ORDER.asc));}}}//分页params.setStart(start);params.setRows(rows);//默认域params.set("df", dfField);//只查询指定域
    //         params.set("fl", content + ",content,id,title,author");//高亮//打开开关params.setHighlight(true);//指定高亮域params.addHighlightField("id");params.addHighlightField(dfField);params.addHighlightField("title");params.addHighlightField("content");params.addHighlightField("author");params.addHighlightField("keywords");//设置前缀params.setHighlightSimplePre("<span style='color:red'>");//设置后缀params.setHighlightSimplePost("</span>");QueryResponse queryResponse = client.query(core,params);SolrDocumentList results = queryResponse.getResults();//获取高亮显示的结果, 高亮显示的结果和查询结果是分开放的Map<String, Map<String, List<String>>> highlight = queryResponse.getHighlighting();for(SolrDocument result : results){ // 将高亮结果合并到查询结果中highlight.forEach((k,v) ->{if(result.get("id").equals(k)){v.forEach((k1,v1) -> {result.setField(k1,v1); // 高亮列合并如结果});}});}return results;}
    }
  7. Solr查询Controller

    **getByBgImage()**方法主要用于获取必应壁纸

    @RestController
    @RequestMapping("/solr")
    public class SolrController {@Autowiredprivate SolrClient client;@Autowiredprivate SolrService solrService;/*** 按条件查询, 条件过滤, 排序, 分页, 高亮显示, 获取部分域信息* @return*/@PostMapping("/search")public AjaxResult search(@RequestBody SolrSearchParam param){if (CollectionUtils.isEmpty(param.getCoreParams())) {return AjaxResult.error("请指定core");}try {return solrService.querySolr(param);} catch (IOException e) {} catch (SolrServerException e) {}return AjaxResult.error("查询失败,请联系服务员");}/*** 获取每日壁纸(必应壁纸)* @param* @return*/@GetMapping("/getBgImageByBy/{idx}")public AjaxResult getByBgImage(@PathVariable String idx){try {// 通过传入1-10的随机idx获取1-10天随机一天的壁纸String s = HttpUtils.sendGet("http://cn.bing.com/HPImageArchive.aspx?format=js&n=1&idx=" + idx);JSONObject jsonObject = JSON.parseObject(s);return AjaxResult.success(jsonObject);} catch (Exception e) {return AjaxResult.success("壁纸获取失败");}}
    }
    

前端搜索页面

在ruoyi微服务的ui中仿照csdn谷歌浏览器插件首页自己写了一个搜索页面页面

1.png

1.png

联系方式

作者:永夜

邮箱:Evernight@aliyun.com

以上内容有不正确的地方烦请指正!🙏🙏🙏

http://www.lryc.cn/news/2416771.html

相关文章:

  • 分享88个ASP整站程序源码,总有一款适合您
  • form表单—2种提交方式
  • Win7系统提示找不到MSVCRTD.DLL文件的解决办法
  • MaskedTextBox
  • 缓存背后的智慧:旁路、读写穿透和写回三种策略全面解析
  • CSS——滤镜(filter )
  • 关于Loadlibrary 失败-找不到指定模块126错误
  • DAS~~
  • ThinkPHP6+Layui自定义分页样式
  • 博客搜索引擎列举|博客搜索引擎的浅比较
  • 多线程开发实战:Java实现多线程四种方式及相关方法原理
  • 端口详解及如何开起端口关闭端口
  • C语言之多线程编程
  • plsql学习笔记
  • MFC窗口之间的消息传递
  • Robot之Setting table部分
  • 从Java角度看区块链实践系列3——P2P网络:区块链P2P网络拓扑结构的演变史
  • 高并发高流量网站架构
  • 史上最简单易懂的 简析utf-8编码
  • C语言实战-贪吃蛇
  • 沟通CTBS物流行业远程接入解决方案
  • STM32CubeMX 下载安装使用(一)
  • H3C交换机配置DHCP中继
  • 编译hyperscan
  • CydiaSubstrate的简单使用
  • 探索MS17-010漏洞利用工具:All-In-One全方位解析
  • mysql用decimal_MySQL数据类型DECIMAL用法详解
  • MySQL - 存储过程 [Stored Procedure] - 学习/实践
  • INA3221和 ESP8266 6通道电流表
  • HTML自动暂停按钮,css 播放暂停按钮实现_html/css_WEB-ITnose