学习视频地址:https://www.bilibili.com/video/av45567492?from=search&seid=14848044148453483902
本篇博客是基于此学习视频以及课程笔记进行学习
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。
用户可以通过HTTP的POST请求,向Solr服务器提交一定格式的XML或者JSON文件,Solr服务器解析文 件之后,根据具体需求对索引库执行增删改操作;用户可以通过HTTP的GET请求,向Solr服务器发送搜索请求,并得到XML/JSON格式的返回结果。Solr 是Apache下的一个顶级开源项目,采用Java开发,基于Lucene。 Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。 Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索应用。
Lucene仅提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目 标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索应用。
Solr的目标是打造一款企业级的搜索引擎系统,它是基于Lucene一个搜索引擎服务器,可以独立运行,通过Solr可 以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。
Solr的各个版本下载地址
http://archive.apache.org/dist/lucene/solr/
先行声明,如果想要直接在Tomcat中部署直接看Tomcat部署也可以
Solr默认提供Jetty(java写的Servlet容器)启动solr服务器。
使用jetty启动: 1. 进入example目录
2. 执行命令:java -jar start.jar
3. 访问地址:http://本机地址:8983/solr
但是企业中一般使用Tomcat作为服务器,所以下面我们一起来看看如何将solr部署在tomcat中。
1. SolrHome和SolrCore
SolrHome是Solr服务器运行的主目录,Solr服务的所有配置信息包括索引库都是在该目录下。
该目录中包括了多个SolrCore目录。 SolrHome和SolrCore是Solr服务器中最重要的两个目录。 SolrCore就是collection1目录,该目录中包含搜索和索引时需要的配置文件和数据文件(比如索引库中的文件)。 每个SolrCore都可以提供单独的搜索和索引服务。
.2. 创建SolrHome和SolrCore
下图中的solr目录就是一个solrhome目录,它就是jetty启动的solr服务使用的solrhome目录。
复制该文件夹到本地的一个目录,把文件名称改为solrhome。(改名不是必须的,只是为了便于理解)
打开solrhome目录确认是否拥有solrcore
3. 配置SolrCore(了解)
其实就是配置SolrCore目录下的conf/solrconfig.xml。
这个文件是来配置SolrCore实例的相关运行时信息。如果使用默认配置可以不用做任何修改。该配置文件中包含了 不少标签,但是我们经常使用的标签有:lib标签、datadir标签、requestHandler标签
1) lib 标签 lib标签可以配置扩展功能的一些jar,用以增强solr本身没有的功能。
比如solr自身没有『数据导入索引库』功能,如果需要使用,则首先要把这些jar复制到指定的目录,然后通过该配 置文件进行相关配置,后面会具体讲解如何配置。
2) datadir标签 dataDir数据目录data。data目录用来存放索引文件和tlog日志文件。
solr.data.dir表示${SolrCore}/data的目录位置
如果不想使用默认的目录也可以通过solrconfig.xml更改索引目录
(建议不修改,否则配置多个SolrCore会报错)
3)requestHandler标签
requestHandler请求处理器,定义了索引和搜索的访问方式。
通过/update维护索引,可以完成索引的添加、修改、删除操作。
通过/select搜索索引。
设置搜索参数完成搜索,搜索参数也可以设置一些默认值,如下:
第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。
第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classes目录下。
第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。
JDK:1.8以上
Solr:1.7
Web服务器:tomcat8
安装步骤
1)单独为solr准备一个服务器(端口8088)(可以不这么做)
2)找到如下目录内容:
3)
4)
注释:我使用的solr是7.7版本的,7.7版本里面没有log4j.properties文件,但是有俩个关于log4j的xml文件,我在启动服务的时候在此处报错,然后我重新下载solr7.1版本的在里面有log4jproperties。没有报错
没错就是这。
参考此博客,更为清晰明了
1、Dashboard
仪表盘,显示了solr实例开始启动运行的时间、版本、系统资源,JVM等
2、Logging
显示solr运行出现的异常或错误
3、Core Admin
4、java properties
Solr在JVM运行环境中的属性信息,包括类路径、文件编码、JVM内存设置等信息。可查看到JAVA相关的一些属性的信息
5、Thread Dump
显示Solr Server中当前活跃线程信息,同时也可以跟踪线程运行栈信息
6、Core selector(重点)
需要在Core Admin里添加了core才有可选项
1)Analysis (重点)
通过此界面可以检测索引分析器和搜索分析器的执行情况
注:solr中,分析器是绑定在域的类型中的
2)dataimport
可以定义数据导入处理器,从关系数据库将数据导入到Solr索引库中,默认没有配置,需要手工配置
3)Document
添加数据
4)Query(重点)
搜索数据
该功能是数据库中数据通过Sql语句方式导入到Solr索引库中
solr下的dist下的jar包
和 mysql的驱动包
如果用的solr版本大于7,在solr中自带有中文分词器,不需要我们使用第三方中文分词器,并且把相对性的jar包导入到项目的lib目录下,并且需要在schame.xml中进行配置
赋值到对应项目的lib目录下
在solr7版本下配置
在C:\Users\84741\Desktop\ssss\solr\solrhome\demo_core\conf(在timcat的一个core中的conf文件夹中)的 managed-schema中添加
添加后就可以在solr的界面端使用中文分词器
1、Field的详解
2、dynamicField详解
3、uniqueKey
其中的id是在Field标签中已经定义好的域名,而且该域名设置为required为true,一个schema / managed-schema文件中必须有且仅有一个唯一键
4、copyFiled
复制域
使用案例:
5、fieldType
Name:指定域类型的名称
Class:指定该域类型对应的solr类型
Analyzer:指定分析器
Type:index、query 分别指定搜索和索引时的分析器
Tokenizer:指定分词器
Filter:指定过滤器
找到solrhome里面的 core 文件 下的conf里的solrconfig.xml文件,添加dataimport
首先查询是否存在dataimport的requestHandler,如果不存在,因此需要手动添加,为了以后便于维护此文件,我们就在requestHandler起始位置就处于requestHandler标签所处的区域
data-config.xml 作用:数据库连接相关信息,sql以及查询结果映射对应域中
在solrconfig.xml同级目录下,创建data-config.xml文件
Query代表:查询的sql语句
Column代表:Sql查询的列名
Name代表:Solr或Feild的域名
q:查询关键字,此参数最为重要,例如q=id:1, 默认为q = *.*.
单个条件:
多个条件:
可以参考此博客,学习solr的基本语法
https://blog.csdn.net/qq_15037231/article/details/79607435
SolrJ是操作Solr的java客户端,它提供了增加、修改、删除,查询Solr索引的java接口、Solr针对Solr提供了Rest的Http接口进行了封装,Solr底层是通过HttpClient中的方法来完成Solr的操作的
搭建Maven工程
1、java对象绑定
SolrJ提供了俩个接口 UpdateResponse 和 QueryResponse 他们可以很方便的处理特定域的对象,可以使程序更容易被理解。SolrJ支持通过@Feild注解隐式转换文档和任何类
每个实例变量在Java对象可以映射在一个相对应的Solr字段中使用field注解
对于Maven构建的项目,pom.xml配置
solr包的依赖
查看data-config.xml配置
2、添加 / 修改索引
在solr中,索引库中都会存在一个唯一键,如果一个Document的id存在,则执行修改操作,如果不存在,则执行添加操作。
/** * 在solr中,索引库都会存在一个唯一键 * 如果一个document的id存在,则进行修改操作,如果不存在,则执行添加操作 * @throws IOException * @throws SolrServerException */ @Test public void addOrUpdate() throws Exception{ //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //提供数据 Shop shop = new Shop(); shop.setTsId(111111); shop.setTsInfo("Solr测试-修改"); shop.setTsSellCount(8888); shop.setTsImagepath("asasa"); shop.setTsPrice(88); shop.setTsShopName("田坤至尊店"); shop.setTsAddressSheng("陕西"); shop.setTsAddressShi("西安"); //执行添加成功 UpdateResponse addBean = client.addBean(shop); //事务提交 client.commit(); System.out.println("添加成功"); client.close(); }
3、删除索引
@Test public void delete() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //client.deleteById 根据Id作为条件进行删除 //client.deleteById("11111"); //client.deleteByQuery 根据查询结果作为条件进行删除 //client.deleteByQuery("*:*"); //清空Solr索引库 client.deleteByQuery("goods_info:电脑"); //事务提交 client.commit(); System.out.println("删除成功"); client.close(); }
4、查询
1)简单的查询
/** * 简单的查询 * @throws Exception */ @Test public void select() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //q:查询关键字 String q = "goods_info:电脑手机"; SolrParams params = new SolrQuery(q); QueryResponse query = client.query(params); List<Shop> list = query.getBeans(Shop.class); System.out.println(list.size()); for (Shop shop : list) { System.out.println(shop); } //事务提交 client.commit(); System.out.println("查询成功"); client.close(); }
因为solr中查询默认是10所以只能查出十条数据
10 Shop(tsId=1555, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+, tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1551, tsInfo=戴尔DELL游匣G315.6英寸英特尔酷睿i7游戏笔记本电脑, tsSellCount=6699, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1554, tsInfo=戴尔DELL游匣G3烈焰版 15.6英寸游戏笔记本电脑(i7, tsSellCount=6399, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1567, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+64GB WiFi版(香槟金), tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1579, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+64GB WiFi版(香槟金), tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1557, tsInfo=荣耀MagicBook 2019 14英寸轻薄窄边框笔记本电脑(AMD锐龙5 3500U 8G 512G FHD IPS 指纹解锁)冰河银, tsSellCount=4049, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1569, tsInfo=荣耀MagicBook 2019 14英寸轻薄窄边框笔记本电脑(AMD锐龙5 3500U 8G 512G FHD IPS 指纹解锁)冰河银, tsSellCount=4049, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=4049.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1560, tsInfo=华为(HUAWEI) MateBook E 2019款 12英寸ACPC全连接轻薄二合一笔记本平板电脑( 钛金灰 高通骁龙850 8G 256G), tsSellCount=3999, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1572, tsInfo=华为(HUAWEI) MateBook E 2019款 12英寸ACPC全连接轻薄二合一笔记本平板电脑( 钛金灰 高通骁龙850 8G 256G), tsSellCount=3999, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=3999.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1559, tsInfo=荣耀MagicBook 英特尔酷睿i7 14英寸轻薄窄边框笔记本电脑(i7-8550U 8G 256G MX150 2G独显 FHD IPS)冰河银, tsSellCount=5399, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) 查询成功
2)复杂的查询
/** * SolrJ 查询索引库查询 * 复杂查询 * 模拟电商 * @throws Exception */ @Test public void selectNan() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //查询的条件 SolrQuery query = new SolrQuery(); //查询关键字 String keyword ="电脑手机"; //1、设置q ————> 主页检索出入框 //判断用户是否对keyword赋值 if(StringUtils.isEmpty(keyword)) { //如果用户没有对keyword进行辅助,查询所有的商品 keyword = "*"; query.set("q",keyword); }else { //如果用输入关键字,进行字符串拼接 query.set("q",keyword); } //2、设置fq //2。1、类别筛选 String goods_addressSheng ="陕西"; //ps:因为我的数据库中没有类别这个数据,所以以省地址来模拟类别操作 if(!StringUtils.isEmpty(goods_addressSheng)){ //如果为空不设置,如果选择了加入查询条件 query.addFilterQuery("goods_addressSheng:"+goods_addressSheng); } //2.2、价格筛选 String goods_price =""; if(!StringUtils.isEmpty(goods_price)) { String[] split = goods_price.split("-"); if(split.length == 1) { query.addFilterQuery("goods_price:"+"["+split[0]+" TO *]"); }else { String pre = split[0]; if(StringUtils.isEmpty(split[0])) { pre = "*"; } query.addFilterQuery("goods_price:["+pre+" TO "+split[1]+"]"); } } //3、排序功能 //sort 1 = 升序 2 = 降序 int sort = 1; if(sort == 1) { query.addSort("goods_price", ORDER.asc); }else if(sort == 2) { query.addSort("goods_price", ORDER.desc); } //4、设置分页功能 /** * mysql 分页语法相似 * start offset 偏移量 * rows rows 返回最大的记录数 */ query.setStart(0); query.setRows(20); //5、设置回显 作用:保护隐私数据 query.setFields("id","goods_info","goods_price"); //6、设置默认域 query.set("df", "goods_info"); //7、高亮设置 //开启高亮功能 query.setHighlight(true); //设置需要加高亮的字段 query.addHighlightField("goods_info"); query.setHighlightSimplePre("<font color='red'>"); query.setHighlightSimplePost("</font>"); QueryResponse queryResponse = client.query(query); List<Shop> list = queryResponse.getBeans(Shop.class); System.out.println(list.size()); //获取到高亮数据 Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting(); for (Shop shop : list) { String tsId = shop.getTsId(); Map<String, List<String>> hinfo = highlighting.get(tsId); List<String> list2 = hinfo.get("goods_info"); //如果用户关键字搜索不为空则可以显示出高亮,反之则无 if(list2 != null) { System.out.println(list2.get(0)+" "+shop.getTsPrice()); }else { System.out.println(shop.getTsInfo()+" "+shop.getTsPrice()); } } //事务提交 client.commit(); System.out.println("查询成功"); client.close(); }
ps:以上只是对于索引库的修改,用户实验,而真正则是要数据库和索引库同时修改