1.概要
百科百科:https://baike.baidu.com/item/Solr/4101582?fr=aladdin
视频学习:https://www.bilibili.com/video/BV1ob411T7NQ?p=9
1)、solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。
2)、用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件(可以是多种格式入json),生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。
2.好处
1)、他是apache下基于lucene上开发出的一款能独立运行开源服务
2)、分词查询
3)、跨表查询,入输入文章内容可以查询、输入文章类目也可查询
4)、由于该索引存储的数据机构机制,查询数据效率很快
3.安装
1)、官网地址和概述图
https://lucene.apache.org/solr/
1)、在win下部署solr应用
进入bin目录下;
启动命令:solr .cmd start;
停止命令:solr stop或 solr stop -all;
查看服务命令:solr status;
2)、以它本身的jetty服务器启动(默认端口8983)
访问地址:http://localhost:8983/solr/#/
效果:
3)、为了方面调用服务以tomcat服务器部署启动
不多说将tomcat减压防止到一个位置
修改对应端口也为8983
验证tomcat是否成功
开始部署将D:\Resources\解索工具\solr\solr-7.1.0\server\solr-webapp下的webapp拷贝到tomcat下webapps下面并取名为solr
然后将D:\Resources\解索工具\solr\solr-7.1.0\server\lib下ext下jar、以metrics开头的jar、gmetric4j-1.0.7.jar复制到D:\Apache\solr\tomcat8-solr\webapps\solr\WEB-INF\lib下
在tomcat/webapps/solr/WEB-INF中新建classes文件,并将
\solr-7.1.0\server\resources下的log4j.properties文件拷贝到
classes里面
在tomcat同级目录下新建solr_home文件夹
将solr-7.1.0\server\solr\下所有文件及文件夹拷贝到solr_home目录下,再将solr-7.1.0下contrib和dist文件夹拷贝到solr_home目录下
在solr_home目录下新建demo_core文件夹,并将solr-7.1.0\server\solr\configsets\sample_techproducts_configs\下的conf拷贝到demo_core下
修改conf下solrconfig.xml文件
修改D:\Apache\solr\tomcat8-solr\webapps\solr\WEB-INF下web.xml文件,去掉注释,修改solr_home路径,然后再注释掉
下面的标签
最后启动tomcat访问: http://localhost:8983/solr/index.html
4.使用
1)、创建一个solr实例
创建一个实例后,下面就有一些技术:
分词器、导入数据、解索查询
2)、集成solr7自带的中文分词器
先将solr-7.1.0\contrib\analysis-extras\lucene-libs下的jar拷贝到WEB-INF/lib下
在D:\Apache\solr\solr_home\demo_core\conf下找到managed-schema并修改,在文件最后加入
<!-- ChineseAnalyzer -->
<fieldType name="solr_cnAnalyzer" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
</analyzer>
</fieldType>
重启服务刷新页面
3)、定义域
在D:\Apache\solr\solr_home\demo_core\conf下的managed-schema文件中添加域,防止中文分词下面就行
<!--
name:为与名称,就是你搜索的字段名称
type:为字段类型,solr_cnAnalyzer这个是自己集成的分词类型
indexed:是否为索引搜索,就是这个字段是不是搜索字段
stored:是否存储
required:是否必传
-->
<field name="prod_pname" type="solr_cnAnalyzer" indexed="true" stored="true" required="true" />
<field name="prod_catalog_name" type="string" indexed="true" stored="true" required="true" />
<field name="prod_price" type="pdouble" indexed="true" stored="true" required="true" />
<field name="prod_description" type="solr_cnAnalyzer" indexed="true" stored="true" required="true" />
<field name="prod_picture" type="string" indexed="false" stored="true" required="true" />
4)、SolrJ使用(就是在java代码中操作)
引入依赖
<!--solr依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
实体与域绑定
配置yml文件
单元测试
package com.itgo.springboot.service;
import com.itgo.springboot.entity.ItProducts;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.params.SolrParams;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;
@SpringBootTest
@MapperScan("com.itgo.springboot.mapper")
@Component
class ProductServiceImplTest {
@Autowired
SolrClient solrClient;
@Test
public void solrTest(){
System.out.println("-----------------" + solrClient);
}
//添加
@Test
public void solrAddTest() throws IOException, SolrServerException {
ItProducts products = new ItProducts();
products.setPid("1003");
products.setPname("测试数据003");
products.setPrice(11d);
products.setPicture("1231.png");
products.setDescription("测试数据描述003");
products.setCatalogName("测试数据类别003");
UpdateResponse updateResponse = solrClient.addBean(products);
solrClient.commit();
System.out.println("--------添加成功--------" + updateResponse);
}
//修改
@Test
public void solrUpdateTest() throws IOException, SolrServerException {
ItProducts products = new ItProducts();
products.setPid("1000");
products.setPname("测试数据002");
products.setPrice(12311.99);
products.setPicture("222.png");
products.setDescription("测试数据描述002");
products.setCatalogName("测试数据类别002");
//添加和修改调用的方法是一样,id存在时就是修改,不存在是就是添加
UpdateResponse updateResponse = solrClient.addBean(products);
solrClient.commit();
System.out.println("--------修改成功--------" + updateResponse);
}
//删除
@Test
public void solrDeleteTest() throws IOException, SolrServerException {
//删除单条数据
UpdateResponse updateResponse = solrClient.deleteById("1000");
//这个是清楚索引库
//solrClient.deleteByQuery("*:*");
solrClient.commit();
System.out.println("--------删除成功--------" + updateResponse);
}
//查询
@Test
public void solrSelectTest() throws IOException, SolrServerException {
//查询所有数据
SolrParams params = new SolrQuery("*:*");
QueryResponse query = solrClient.query(params);
//列表
List<ItProducts> listAll = query.getBeans(ItProducts.class);
//总记录数
Long count = query.getResults().getNumFound();
System.out.println("总记录数为:" + count);
for(ItProducts p : listAll){
System.out.println("ID:" +p.getPid()+ "----名称:" + p.getPname());
}
}
//较复杂查询
@Test
public void solrSelectFZTest() throws IOException, SolrServerException {
//查询所有数据
SolrQuery query = new SolrQuery();
//q
query.set("q","prod_pname:测试数据");
//fq 过滤查询
//query.setFilterQueries("prod_catalog_name:测试数据类别003");
query.addFilterQuery("prod_catalog_name:测试数据类别003 or prod_catalog_name:测试数据类别001 or prod_catalog_name:测试数据类别002");
//价格区间查询 prod_price:[0 TO *]
query.addFilterQuery("prod_price:[0 TO *]");
//排序 SolrQuery.ORDER.asc/SolrQuery.ORDER.desc
query.addSort("prod_price", SolrQuery.ORDER.asc);
//分页 start页偏移量【(page - 1)*rows】 rows页大小
query.setStart(0);
query.setRows(2);
QueryResponse queryResponse = solrClient.query(query);
//列表
List<ItProducts> list = queryResponse.getBeans(ItProducts.class);
//总记录数
Long count = queryResponse.getResults().getNumFound();
System.out.println("总记录数为:" + count);
for(ItProducts p : list){
System.out.println("ID:" +p.getPid()+ "----名称:" + p.getPname() + "----价格:" + p.getPrice());
}
}
}