搜索
1.为什么要使用搜索
如何实现互联网产品中的搜索功能。
Solr是一个款基于Lucene全文搜索引擎基础之上的一款搜索的产品,它更适合于静态资源的搜索。相比之下,ElasticSearch更加适合于动态资源的搜索,比如日志的检索等等。
solr的介绍
![v2-15154d2ddf26ab83682825924aee0e7c_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-15154d2ddf26ab83682825924aee0e7c_b.jpg)
Solr支持高性能、高可用、高并发的一个nosql数据库,具有一个可视化的管理界面,而且提供了restful风格的api。
solr的初体验
solr的安装——基于docker安装
步骤一:先创建一个文件夹: /usr/local/docker/solr
步骤二:在solr文件夹内创建docker-compose.yml文件
version: '3.1'
services:
solr:
image: solr:7.1.0
restart: always
container_name: solr
ports:
- 8983:8983
步骤三: 启动容器 docker-compose up -d
步骤四: 通过浏览器访问solr的管理界面 http://192.168.2.154:8983
solr里是如何存放数据的?
对于mysql数据库来说, 数据库 qf-nz1905 表: t_product t_product_desc 字段: id pname price
对于solr来说,没有数据库之分,只有域和字段的概念,域就相当于是表,字段就相当于是表里的字段。
Solr核心技术详解
solr搜索的关键技术——分词技术
在solr索引库中的数据,通过分词技术将数据进行分词,分词以后数据中会有多个词。比如
“这是一部非常厉害的手机”==》“这”“是”“一部”“非常”“厉害”“的”“手机”,当使用关键字进行检索时,只要关键字匹配上数据的某一个词,那么该数据被命中,就能检索出来。
分词能随便分吗?
“长春市长春药店”==》长春 市长 春药 店
ikanalyzer分词器的安装
步骤一:创建文件夹
/usr/local/docker/solr:用于存放 docker-compose.yml 配置文件
/usr/local/docker/solr/ikanalyzer:用于存放 Dockerfile 镜像配置文件
步骤二:在solr下创建docker-compose.yml文件
version: '3.1'
services:
solr:
build: ikanalyzer
restart: always
container_name: solr
ports:
- 8983:8983
volumes:
- ./solrdata:/opt/solrdata
步骤三:在ikanalyzer文件夹内创建Dockerfile文件(自定义镜像用的)
FROM solr:7.1.0
# 创建 Core
WORKDIR /opt/solr/server/solr
RUN mkdir ik_core
WORKDIR /opt/solr/server/solr/ik_core
RUN echo 'name=ik_core' > core.properties
RUN mkdir data
RUN cp -r ../configsets/sample_techproducts_configs/conf/ .
# 安装中文分词
WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF/lib
ADD ik-analyzer-solr5-5.x.jar .
ADD solr-analyzer-ik-5.1.0.jar .
WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF
ADD ext.dic .
ADD stopword.dic .
ADD IKAnalyzer.cfg.xml .
# 增加分词配置
COPY managed-schema /opt/solr/server/solr/ik_core/conf
WORKDIR /opt/solr
步骤四:上传所需要的ik资源包到该路径下
![v2-9fa281d95a9d3554339342dface513d7_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-9fa281d95a9d3554339342dface513d7_b.jpg)
步骤五: 回到solr路径下,通过docker-compose up -d来启动
向solr索引库中插入数据
向solr库中插入数据(键值对)之前,要先将数据的键在solr中进行注册,进行注册的目的是让solr知道这个数据要使用怎么样的分词器中的字段(字段名/字段类型)进行分词。
- 在solr中注册字段
在managed-schema文件末尾添加以下内容
![v2-118e24eb8c866b7033c27705dfad70c8_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-118e24eb8c866b7033c27705dfad70c8_b.jpg)
保存完文件后记得将文件上传到容器中,并重启容器
# 复制到容器
docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf
# 重启容器
docker-compose restart
- 如何设计Javabean
sql的操作
-- 希望拿到 商品的id、 商品的名称、商品的售价、商品的图片、商品的描述
SELECT
a.pid,
a.pname,
a.sale_price,
a.pimage,
b.pdesc
FROM
t_product a
LEFT JOIN t_product_desc b
ON a.pid = b.pid
![v2-9bd69a8be790ea9898163226ba991cbc_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-9bd69a8be790ea9898163226ba991cbc_b.jpg)
小结
要装带有核心域(ik)的solr,装完以后我们需要往solr中插入能被搜索的数据。在插入数据之前,一定要将数据的字段在solr中进行注册。注册时需要指明字段名以及字段的类型。之后,才能往solr中插入数据。
在solr网页端进行数据的操作
添加数据
![v2-5c2a33c17df3bd904f9316b6a04bb3e3_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-5c2a33c17df3bd904f9316b6a04bb3e3_b.jpg)
查询数据
高亮查询
![v2-78ea12a533092c01a04b9e7eb526e0c5_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-78ea12a533092c01a04b9e7eb526e0c5_b.jpg)
使用复制域来查询
要想通过一个关键字来匹配多个字段,那么就需要先给这些字段设置复制域。设完以后就可以直接通过复制域来查询。也就是说在复制域中匹配的这些字段的数据就可以被命中。
也就是说: 要在商品名称和商品描述中同时匹配关键字,所以要用复制域。
步骤一:在managed-schema文件中创建复制域
# 复制域(Solr 的搜索优化功能,将多个字段域复制到一个域里,提高查询效率)
<field name="t_item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="t_product_name" dest="t_item_keywords"/>
<copyField source="t_product_pdesc" dest="t_item_keywords"/>
步骤二: 在容器中更新该managed-schema文件,注意,如果更新完后没有效果,重新创建镜像,重新启动容器。
# 复制到容器
docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf
# 重启容器
docker-compose restart
步骤三: 在管理界面中使用复制域来查询
![v2-fbfab500e7cbd51e52009289fd9a5bba_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-fbfab500e7cbd51e52009289fd9a5bba_b.jpg)
删除数据
- 根据id来删除
<delete>
<id>1</id>
</delete>
<commit/>
- 根据查询结果来删除
<delete>
<query>*:*</query>
</delete>
<commit/>
![v2-16985a7f2d258820771323882a59f6eb_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-16985a7f2d258820771323882a59f6eb_b.jpg)
在Springboot中整合solr
1.创建springboot项目,添加solr的依赖
![v2-16a9fcd2263d13185438289e0fb5a7e4_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-16a9fcd2263d13185438289e0fb5a7e4_b.jpg)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.编写配置文件
spring:data:solr:host: http://192.168.2.154:8983/solr/ik_core
注意 这个地址可以通过浏览器地址栏复制过来,要去掉”#”
3.向solr库中插入数据的流程
![v2-e7911133da71637a88dd4c0092f27c57_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-e7911133da71637a88dd4c0092f27c57_b.jpg)
1)从MySQL数据库中得到所有数据
Sql:
SELECT
a.pid AS id,
a.pname AS t_product_name,
a.sale_price AS t_product_sale_price,
a.pimage AS t_product_pimage,
b.pdesc AS t_product_pdesc
FROM
t_product a
LEFT JOIN t_product_desc b
ON a.pid = b.pid
- 在Springboot中整合MyBatis
步骤一:引入依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
步骤二:
准备好entity和mapper
步骤三:
在springboot启动类上打上注解
@MapperScan("com.qf.my.spring.boot.solr.demo.mapper")
步骤四:
<build>
<resources>
<resource>
<includes>
<include>**/*.xml</include>
</includes>
<directory>src/main/java</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
步骤五:
Mysql的连接配置信息
spring:data:solr:host: http://192.168.2.154:8983/solr/ik_coredatasource:url: jdbc:mysql://localhost:3306/qf-solr?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456
2)向solr库中插入数据
![v2-f7b3f601a2507758485507c9eae8740b_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=1c848c3a-112a-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-f7b3f601a2507758485507c9eae8740b_b.jpg)
步骤一:遍历商品集合,将商品封装成SolrInputDocument对象,并存入到集合中
步骤二:将集合添加到solr库中,注意,添加完后要commit
@SpringBootTestclass MySpringBootSolrDemoApplicationTests {
@Autowiredprivate SolrClient solrClient;//通过调用solrClient的Restful API来操作solr
@Autowiredprivate TProductSearchDTOMapper mapper;/** * 从数据库中检索出数据,将数据插入到solr库中 */
@Testpublic void TestInsertDataToSolr(){//从数据库中获取数据
List<TProductSearchDTO> products = mapper.selectAll();//存放所有的doc的集合
List<SolrInputDocument> docs = new ArrayList<>();//遍历products集合,将每一个product对象封装成一个SolrInputDocument对象for (TProductSearchDTO product : products) {
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id",product.getId());
doc.setField("t_product_name",product.gettProductName());
doc.setField("t_product_sale_price",product.gettProductSalePrice().floatValue());
doc.setField("t_product_pimage",product.gettProductPimage());
doc.setField("t_product_pdesc",product.gettProductPdesc());//将doc对象存入到集合中
docs.add(doc);
}//将该集合添加到solr库中try {solrClient.add(docs);solrClient.commit();//不要忘了
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}