网易首页 > 网易号 > 正文 申请入驻

开发人员如何快速定制化实现一个基于Solr的搜索引擎

0
分享至


Solr实现全文搜索

  • Solr
  • Apache Solr特点
  • 搜索引擎
  • 搜索引擎组件
  • 搜索引擎工作流程
  • 分词技术
  • 中文分词算法
  • 基于字符串匹配
  • 基于统计及机器学习的分词方式
  • IKAnalyzer
  • 部署Solr并安装IKAnalyzer
  • Solr分析功能
  • 修改managed-schema配置业务系统字段
  • 复制配置到容器
  • 重启容器
  • SpringBoot整合Solr
  • 创建搜索服务接口
  • 创建搜索服务提供者
  • 创建消费者
  • 搜索服务

Solr

  • Solr是一个可扩展的,可部署,搜索,存储引擎,优化搜索大量以文本为中心的数据库Solr是开源搜索平台,用于构建搜索应应用程序建立在Lucene(全文搜索引擎)之上Solr是企业级的,快速的和高度可扩展的,使用Solr构建的应用程序可以提供高性能,但是非常复杂Solr可以和Hadoop一起使用:由于Hadoop处理大量数据,Solr可以从大的数据源中找到所需信息.Solr不仅限于搜索,也可以用于存储.和其它NoSQL数据库一样,是一种非关系数据存储和处理技术

Apache Solr特点

Solr是Lucene的Java API包装,使用Solr,就可以使用Lucene的所有功能

  • RESTful API: 要与Solr通信,可以使用RESTful服务与Solr通信,可以使用XML,JSON,CSV等格式的文件作为输入文档,并以相同的文件格式获取结果
  • 全文搜索: Solr提供了全文搜索所需的所有功能:令牌,短语,拼写检查,通配符,自动完成
  • 企业准备: 根据企业或组织的需要,Solr可可以部署在任何类型的系统:独立,分布式,云
  • 灵活可扩展: 通过扩展Java类并进行相关配置,可以定制Solr组件
  • NoSQL数据库: Solr可以用作大数量级的NoSQL数据库,可以沿着集群分布搜索任务

搜索引擎

  • 搜索引擎:搜索引擎是庞大的互联网资源数据库,如网页,新闻组,程序,图像等有助于在网上定位信息用户可以通过以关键字或短语的形式将查询传递到搜索引擎中来搜索信息,然后搜索引擎搜索其数据库并向用户返回相关链接

搜索引擎组件

搜索引擎有三个组件:

  • Web爬虫: 一个收集网络信息的软件组件
  • 数据库: Web上的所有信信息都存储在数据库中,包含大量的Web资源
  • 搜索接口: 这个组件是用户和数据库之间的接口,帮助用户搜索数据库

搜索引擎工作流程

  • 获取原始内容: 任何搜索应用程序的第一步是收集要进行搜索的目标内容
  • 构建文档: 从原始内容构建文档,让搜索应用程序可以很容易理解和解释
  • 分析文档: 在索引开始之前,将对文档进行分析
  • 索引文档: 当文档被构建和分析后,下一步是对文档建立索引,以便可以基于特定键而不是文档的全部内容来检索该文档.索引类似于在书开始页或末尾处的目录索引,其中常见单词以页码显示,使得这些单词可以快速追踪,而不是搜索整本书
  • 用于搜索的用户接口: 当索引数据库就绪,应用程序就可以执行搜索操作.为了帮助用户进行搜索,应用必须提供用户接口,用户可以在用户接口中输入文本并启动搜索过程
  • 构建查询: 当用户做出搜索文本的请求,应用程序应该使用该文本准备查询对象,然后可以使该查询对象来查询索引数据库以获得相关细节
  • 搜索查询: 使用查询对象,检查索引数据库以获取相关详细信息和内容文档
  • 渲染结果: 当收到所需结果,应用程序应决定如何使用用户界面向用户显示搜索结果

分词技术

  • 分词技术: 搜索引擎针对用户提交查询的关键词串进行的查询处理后,根据用户的关键词串用各种匹配方法进行分词的一种技术

中文分词算法

基于字符串匹配

  • 基于字符串匹配:即扫描字符串,如果发现字符串的子串和词相同,就算匹配这类分词通常会加入一些启发式规则:正向/反向最大匹配,长词优先
  • 基于字符串匹配算法优点:速度快都是O(n)时间复杂度实现简单效果尚可
  • 基于字符串匹配算法缺点:对歧义和未登录词处理不好
  • ikanalyzer,paoding等就是基于字符串匹配的分词

基于统计及机器学习的分词方式

  • 基于统计及机器学习的分词方式:基于人工标注的词性和统计特征,对中文进行建模. 即根据观测到的数据(标注好的语料)对模型参数进行估计.即 训练在分词阶段再通过模型计算各种分词出现的概率,将概率最大的分词结果作为最终结果常见的序列标注模型:HMM,CRF
  • 基于统计及机器学习的分词方式优点:可以很好地处理歧义和未登录问题效果比基于字符串匹配算法更好
  • 基于统计及机器学习的分词方式缺点:需要大量的人工标注数据较慢的分词速度

IKAnalyzer

  • IKAnalyzer是一个开源的,基于Java语言开发的轻量级中文分词工具包
  • 基于文本匹配,不需要投入大量的人力进行训练和标注
  • 可以自定词典,方便加入特定领域的词语,能分出多粒度的结果

部署Solr并安装IKAnalyzer

  • 创建/usr/local/docker/solr/ikanalyzer目录

/usr/local/docker/solr用于存放docker-compose.yml配置文件/usr/local/docker/solr/ikanalyzer用于存放Dockerfile镜像配置文件

  • docker-compose.yml

version: '3·1'services: solr: build: ikanalyzer restart: always container_name: solr ports: - 8983:8983 volumes: - ./solrdata:/opt/solrdata

  • Dockerfile(在/usr/local/docker/solr/ikanalyzer中需要有文件:ik-analyzer-solr5-5·x·jar,solr-analyzer-ik-5·1·0·jar,ext·dic,stopword·dic,IKAnalyzer·cfg·xml,managed-schema)

FROM solr# 创建CoreWORKDIR /opt/solr/server/solrRUN mkdir ik_coreWORKDIR /opt/solr/server/solr/ik_coreRUN echo 'name=ik_core' > core·propertiesRUN mkdir dataRUN cp -r ··/configsets/sample_techproducts_configs/conf/ ·# 安装中文分词WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF/libADD ik-analyzer-solr5-5.x.jar .ADD solr-analyzer-ik-5.1.0.jar .WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INFADD ext.dic .ADD stopword.dic .ADD IKAnalyzer.cfg.xml .# 增加分词配置COPY managed-schema /opt/solr/server/solr/ik_core/confWORKDIR /opt/solr

  • 构建镜像: 在/usr/local/docker/solr中执行命令

docker-compose up -d

Solr分析功能

修改managed-schema配置业务系统字段

  • Solr中自带的相同字段无需再添加,其它字段需要手动添加Solr字段(通过编辑managed-schema配置文件来手动添加Solr字段)

复制配置到容器

docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf

重启容器

docker-compose restart

  • 在Solr的Web界面可以进行CRUD操作

SpringBoot整合Solr

创建搜索服务接口

  • 创建myshop-service-search-api项目,该项目只负责定义接口
  • pom.xml

4.0.0

com.funtl

myshop-dependencies

1.0.0-SNAPSHOT

../myshop-dependencies/pom.xml

myshop-service-search-api

jar

  • 在项目中创建SearchService接口

package com.oxford.myshop.service.search.api;public interface SearchService {List

search(String query,int page,int rows);}

  • 创建TbItemResult用于返回Solr结果集

package com.oxford.myshop.service.search.domain;import java.io.Serializable;public class TbItemResult implements Serializable {private long id;private long tbTtemCid;private String tbItemCname;private String tbItemTitle;private String tbItemSellPoint;private String tbItemDesc;public long getId(){return id;}public void setId(long id){this.id=id;}public long getTbTtemCid(){return tbTtemCid;}public void setTbTtemCid(long tbTtemCid){this.tbTtemCid=tbTtemCid;}public String getTbItemCname(){return tbItemCname;}public void setTbItemCname(String tbItemCname){this.tbItemCname=tbItemCname;}public String getTbItemTitle(){return tbItemTitle;}public void setTbItemTitle(String tbItemTitle){this.tbItemTitle=tbItemTitle;}public String getTbItemSellPoint(){return tbItemSellPoint;}public void setTbItemSellPoint(String tbItemSellPoint){this.tbItemSellPoint=tbItemSellPoint;}public String getTbItemDesc(){return tbItemDesc;}public void setTbItemDesc(String tbItemDesc){this.tbItemDesc=tbItemDesc;}}

创建搜索服务提供者

  • 创建myshop-service-search-provider服务提项目供者
  • MyShopServiceSearchProviderApplication

package com.oxford.myshop.service.search.provider;@EnableHystrix@EnableHystrixDashboard@SpringBootApplication(scanBasePackages="com.oxfrod.myshop")@MapperScan(basePackages="com.oxford.myshop.service.search.provider.mapper")public class MyShopServiceSearchProviderApplication {public static void main(String[] args) {SpringApplication.run(MyShopServiceSearchProviderApplication·class,args);Main.main(args);}}

  • 在项目中创建TbItemResultMapper接口用于查询MySQL中的数据,用于插入到Solr数据库中

package com.oxford.myshop.service.search.provider.mapper;@Respositorypublic interface TbItemResultMapper {List

selectAll();}

Spring的四大注解:1. @Controller2. @Service3. @Component4. @Repository

  • 在resource中创建mapper包用于创建TbContentCategoryMapper.xml

select a.id, a.title as tb_item_title, a.sell_point as tb_item_sell_point, a.cid as tb_item_cid, b.name as tb_item_cname, c.item_desc as tb_item_desc from tb_item as a left join tb_item_cat as b on a.cid=b.id left join tb_item_desc as c on a.id=c.item_id

初始化Solr:public void initSolr() {List

tbItemResult=tbItemResultMapper.selectAll();try{SolrInputDocument document=null;for(TbItemResult tbItemResult:tbItemResults){document=new SolrInputDocument();document.addFiled("id",tbItemResult.getId());document.addFiled("tb_item_cid",tbItemResult.getTbItemCid());document.addFiled("tb_item_cname",tbItemResult.getTbItemCname());document.addFiled("tb_item_title",tbItemResult.getTbItemTitle());document.addFiled("tb_item_sell_point",tbItemResult.getTbItemSellPoint());document.addFiled("tb_item_desc",tbItemResult.getTbItemDesc());solrClient.add(document);solrClient.commit();}}catch(SolrServerException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------搜索Solr:public void searchSolr(){SolrQuery query=new SolrQuery();// 设置查询条件query.setQuery("手机");// 分页查询query.setStart(0);query.setRows(10);// 设置查询的默认域query.set("df","tb_item_keywords");// 设置高亮显示query.setHighlight(true);query.addHighlightField("tb_item_title");query.setHighlightSimplePre("");query.setHighlightSimplePost("");// 开始查询try{QueryResponse queryResponse=solrClient.query(query);SolrDocumentList results=queryResponse.getResults();// 获取高亮Map

>> highlighting=queryResponse.getHighlighting();for(SolrDocument result:results){List

strings=highlighting.get(result.get("id")).get(result.get("tb_item_title"))if(strings!=null&&strings.size()>0){String title=strings.get(0);System.out.println(title);}}}catch(SolrServerException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}

  • 创建SearchServiceImpl实现SearchService接口

package com.oxford.myshop.service.search.provider.api.impl;@Service(version="${services.versions.search.v1}")public class SearchServiceImpl implements SearchService{@Autowiredprivate SolrClient solrClient;@Overridepublic List

search(String query,int page,int rows){List

searchResults=Lists.newArrayList();SolrQuery query=new SolrQuery();// 设置查询条件query.setQuery("手机");// 分页查询query.setStart((page-1)*rows);query.setRows(rows);// 设置查询的默认域query.set("df","tb_item_keywords");// 设置高亮显示query.setHighlight(true);query.addHighlightField("tb_item_title");query.setHighlightSimplePre("");query.setHighlightSimplePost("");// 开始查询try{QueryResponse queryResponse=solrClient.query(query);SolrDocumentList results=queryResponse.getResults();// 获取高亮Map

>> highlighting=queryResponse.getHighlighting();for(SolrDocument solrDocument:solrDocuments){TbItemResult result=new TbResult();result.setId(Long.parseLong(String.valueOf(solrDocument.get("id"))));result.setTbItemCid(Long.parseLong(String.valueOf(solrDocument.get("tb_item_cid"))));result.setTbItemCname((String)solrDocument.get("tb_item_cname"));result.setTbItemTitle((String)solrDocument.get("tb_item_title"));result.setTbItemSellPoint((String)solrDocument.get("tb_item_sell_point"));result.setTbItemDesc((String)solrDocument.get("tb_item_desc"));String tbItemTitle="";List

list=highlighting.get(result.get("id")).get(result.get("tb_item_title"))if(list!=null&&lsit.size()>0){String title=list.get(0);}else{tbItemTitle=(String)solrDocument.get("tb_item_title");}result.setTbItemTitle(tbItemTitle);searchResults.add(result);}}catch(SolrServerException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}return searchResults;}}

创建搜索服务消费者

  • 创建搜索服务消费者myshop-service-search-consumer对Solr数据库中的数据进行检索
  • MyShopServiceSearchConsumerApplication

package com.oxford.myshop.service.search.consumer;@EnableHystrix@EnableHystrixDashboard@SpringBootApplication(scanBasePackages="com.oxford.myshop",exclude=DataSourceAutoConfiguration·class)public class MyShopServiceSearchConsumerApplication{public static void main(String[] args){SpringApplication.run(MyShopServiceSearchConsumerApplication·class,args);Main.main(args);}}

  • SearchController

package com.oxford.myshop.service.search.consumer.controller;@RestControllerpublic class SearchController{@Reference(version="${services.versions.search.v1}")private SearchService searchService;@RequestMapping(value="search/{query}/{page}/{rows}",method=RequestMethod·GET)public List

search(@PathVariable(required=true) String query,@PathVariable(required=true) int page,@PathVariable(required=true) int rows){return searchService.search(query,page,rows)}}

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
泽连斯基致函中方,信中阐述乌方和谈条件,希望中方斡旋俄乌冲突

泽连斯基致函中方,信中阐述乌方和谈条件,希望中方斡旋俄乌冲突

老文的快乐生活呀
2024-06-06 18:07:46
潜伏美国37年的中共谍王暴露始末,因国际惯例,我方无法进行交换

潜伏美国37年的中共谍王暴露始末,因国际惯例,我方无法进行交换

干史人
2024-05-25 19:18:25
全国人均寿命排行:决定寿命的行为,睡眠第9,跑步第2,第一是…

全国人均寿命排行:决定寿命的行为,睡眠第9,跑步第2,第一是…

华人星光
2024-05-20 12:03:06
首进法网决赛!鲍里妮2-0安德列娃 将战世界第一斯瓦泰克争冠

首进法网决赛!鲍里妮2-0安德列娃 将战世界第一斯瓦泰克争冠

醉卧浮生
2024-06-07 00:34:26
重磅!湖人将聘请康大冠军教头赫尔利成为新帅 双方将签巨额合同

重磅!湖人将聘请康大冠军教头赫尔利成为新帅 双方将签巨额合同

厝边人侃体育
2024-06-06 19:02:13
董军刚划红线,不到48小时,荷兰军舰强闯台海,中方当场连将两军

董军刚划红线,不到48小时,荷兰军舰强闯台海,中方当场连将两军

影孖看世界
2024-06-04 20:52:23
刚刚,哈马斯给了以色列一把刀

刚刚,哈马斯给了以色列一把刀

西楼饮月
2024-06-05 22:23:15
唐尚珺迎来16次高考,去年想上却未录取,张雪峰一针见血指出问题

唐尚珺迎来16次高考,去年想上却未录取,张雪峰一针见血指出问题

智学园
2024-06-06 19:52:06
拜登威胁出兵台海,话音刚落,北约国家在华表态:将恪守“一中”

拜登威胁出兵台海,话音刚落,北约国家在华表态:将恪守“一中”

有凤Talk
2024-06-05 16:59:43
女子趁理发师工作时,伸手摸向敏感部位,网友调侃:这钱真难赚

女子趁理发师工作时,伸手摸向敏感部位,网友调侃:这钱真难赚

看晓天下事
2024-05-26 18:38:25
村委会的故事还在继续着,作为吃瓜群众的我有几个疑问?

村委会的故事还在继续着,作为吃瓜群众的我有几个疑问?

翻开历史和现实
2024-05-31 13:25:58
别急着换电车!明年价格大跌,你可能要后悔了

别急着换电车!明年价格大跌,你可能要后悔了

奔跑的赛场
2024-06-06 18:11:46
严查电动自行车,为什么还要大力推广“共享”电动自行车

严查电动自行车,为什么还要大力推广“共享”电动自行车

糖果屋主
2024-06-07 00:57:06
“当初换条路,就不会如此下场!”

“当初换条路,就不会如此下场!”

槽逻辑
2024-06-05 17:59:42
塔图姆谈22年总决赛:勇士是支特殊的球队,他们没犯太多错误

塔图姆谈22年总决赛:勇士是支特殊的球队,他们没犯太多错误

懂球帝
2024-06-06 17:20:18
高考前夕,奶奶用霉肉包粽子,逼我吃下,我笑着让给弟弟,她急了

高考前夕,奶奶用霉肉包粽子,逼我吃下,我笑着让给弟弟,她急了

深夜列车故事集
2024-06-06 11:54:21
广州高考生遇堵车,交警铁骑护送到考点!路线隐患此前已排查

广州高考生遇堵车,交警铁骑护送到考点!路线隐患此前已排查

南方都市报
2024-06-07 10:08:14
太惨了!驴友尸体还捆在一起,2人生前视频细节被曝光 令人窒息

太惨了!驴友尸体还捆在一起,2人生前视频细节被曝光 令人窒息

叶良辰
2024-06-05 21:02:48
毛晓彤求你别再整了!在《庆余年》里假体都要飞出来了,太吓人

毛晓彤求你别再整了!在《庆余年》里假体都要飞出来了,太吓人

谈娱新语
2024-05-24 22:23:27
再见皇马!标价1.5亿!暗中联络瓜帅,转投曼城,无视佛爷好意

再见皇马!标价1.5亿!暗中联络瓜帅,转投曼城,无视佛爷好意

阿泰希特
2024-06-06 11:47:58
2024-06-07 11:36:49
攻城狮Chova
攻城狮Chova
一位攻城狮的自我修养
98文章数 28关注度
往期回顾 全部

科技要闻

马斯克创造人类历史,SpaceX星舰试飞成功

头条要闻

周大福深圳工厂员工:现在剩几十个人 机器也快搬完了

头条要闻

周大福深圳工厂员工:现在剩几十个人 机器也快搬完了

体育要闻

国足进球功臣捂脸沮丧 伊万表情凝重

娱乐要闻

汤唯抵达巴黎将担任奥运火炬手

财经要闻

身陷退市股的投资者:我的钱瞬间没了

汽车要闻

2.0T混动售20.98万元起 福特蒙迪欧运动版上市

态度原创

艺术
本地
游戏
健康
公开课

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

本地新闻

我和我的家乡|踏浪营口,心动不止一夏!

《龙腾世纪4》没有多人元素:纯粹的单人叙事驱动游戏

晚餐不吃or吃七分饱,哪种更减肥?

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版