一.基本概念
Apache Solr是一个开源搜索平台,主要用于构建搜索应用程序,也可以存储数据,类似于NoSQL数据库。它是对Apache Lucene(全文搜索引擎)的一个封装。
使用流程
二.基本使用
1.下载地址:https://solr.apache.org/downloads.html
2.访问地址:域名:端口/solr
3.创建核心core (core类似于数据库)
(1)在bin目录下执行命令
solr create -c 核心名
创建完核心存储的位置:
(2)存储数据(将mysql数据存储到solr中)
①\server\solr\product(自己创建的核心名)文件夹下,新建一个“data-config.xml”。
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource name="jdbcDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://192.168.81.135:3306/solr"
user="root" password="root"/>
<document>
<entity name="product"
query="SELECT p.id, p.name,p.price,m.name merchant,c1.shortname city,c2.shortname province FROM product p LEFT JOIN merchant m ON
p.merchant_id = m.id
LEFT JOIN
city c1
ON
m.city_id = c1.id
LEFT JOIN
city c2
ON
c1.pid = c2.id" >
<field column="id" name="id"/>
<field column="name" name="name"/>
<field column="price" name="price"/>
<field column="merchant" name="merchant"/>
<field column="city" name="city" />
<field column="province" name="province" />
</entity>
</document>
</dataConfig>
③在solr-8.8.1\server\solr\product(自己创建的核心名)\conf 下编辑managed-schema文件,添加如下内容。 type=“text_general” 是自带的分词器,下面配置的是ik分词器。分词需要相关jar包和配置。请将下面的type=“text_ik” 改成 type=“text_general” .
<field name="city" type="text_ik" indexed="true" stored="true"/>
<field name="merchant" type="text_ik" indexed="true" stored="true"/>
<field name="name" type="text_ik" indexed="true" stored="true"/>
<field name="price" type="pdouble" indexed="true" stored="true"/>
<field name="province" type="text_ik" indexed="true" stored="true"/>
④在solr-8.8.1\server\solr\product(自己创建的核心名)\conf 下编辑solrconfig.xml,新增如下内容。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
⑤添加jar包
将solr-8.8.1\dist下的solr-dataimporthandler-8.8.1.jar 和 mysql驱动jar包放到solr-8.8.1\server\solr-webapp\webapp\WEB-INF\lib文件下。
⑥管理界面导入数据
三.Admin管理页面的CRUD操作
注意:id 不存在则添加,存在则修改。文档对应一条记录。
四、分词器
1.原理
Solr创建的索引方式是分词器的倒排索引。
正排索引:文档id对应关键词。文章找词。
倒排索引:关键词对应文档id。词找文章。
2.IK Analyzer 中文分词器
下载地址:https://github.com/magese/ik-analyzer-solr
配置完需要重新导入数据才能生效,因为导入数据时就已经进行分词了。
<!-- https://mvnrepository.com/artifact/com.github.keran213539/IK_Analyzer -->
<dependency>
<groupId>com.github.keran213539</groupId>
<artifactId>IK_Analyzer</artifactId>
<version>2012FF_hf1_1</version>
</dependency>
五.Solrj操作solr
1.实体类
public class Product {
@Field
private String id;
//指定solr中的文档名称
@Field("name")
private String name;
@Field
private Double price;
@Field
private String merchant;
@Field
private String provice;
@Field
private String city;
// get/set toSting 方法省略。
}
2.测试
/**
* SolrJ增删改查
*/
public class Test1 {
//连接Solr
private HttpSolrClient client = new HttpSolrClient.Builder("http://127.0.0.1:8983/solr").build();
@Test
public void test1() throws IOException, SolrServerException {
//增加
Product product = new Product();
product.setId("200");
product.setCity("铜仁市");
product.setMerchant("迁哥的店");
product.setName("时尚女装");
product.setProvice("贵州");
product.setPrice(55.5);
UpdateResponse updateResponse = client.addBean("product",product);
//提交
client.commit("product");
//响应状态 0-成功
int status = updateResponse.getStatus();
System.out.println(status);
}
//测试查询
@Test
public void testQuery() throws IOException, SolrServerException {
SolrDocument solrDocument = client.getById("product", "200");
//文档解析器
DocumentObjectBinder binder = client.getBinder();
//将solrDocument转为自定义对象Product
Product product = binder.getBean(Product.class, solrDocument);
System.out.println(product);
}
/**
* 其他条件查询
*/
@Test
public void testQuery2() throws IOException, SolrServerException {
SolrQuery solrQuery = new SolrQuery();
// solrQuery.set("q","name:衬衫 and name:男"); 满足其一
/* solrQuery.set("q","name:衬衫");
solrQuery.set("fq","price:[50 TO 100]");
solrQuery.set("sort","price asc");
solrQuery.set("start","0");
solrQuery.set("rows","3");*/
//等价写法
solrQuery.setQuery("name:衬衫");
solrQuery.setFilterQueries("price: [50 TO 100]");
solrQuery.setSort("price",SolrQuery.ORDER.asc);
solrQuery.setStart(0);
solrQuery.setRows(3);
//高亮
solrQuery.setHighlight(true);//启用高亮查询
solrQuery.addHighlightField("name"); //高亮字段
solrQuery.setHighlightSimplePre("<font color='red'>");
solrQuery.setHighlightSimplePost("</font>");
QueryResponse queryResponse = client.query("product", solrQuery);
//获取高亮结果
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
//转为集合list
List<Product> productList = queryResponse.getBeans(Product.class);
//将普通结果的字段name改为高亮结果
/**
* "highlighting":{
* "3":{
* "name":["男装 麻棉<font color=\"red\">衬衫</font>(短袖) 414574 优衣库UNIQLO"]},
* "4":{
* "name":["男装 泡泡纱格子<font color=\"red\">衬衫</font>(短袖) 416943 优衣库UNIQLO"]},
* "2":{
* "name":["男装 DRY EASY CARE牛津纺<font color=\"red\">衬衫</font>(短袖) 414569 优衣库UNIQLO"]},
* "5":{
* "name":["男士<font color=\"red\">衬衫</font>商务免烫职业上班工作夏季抗皱修身正装衬衣白衬衫男短袖"]},
* "22":{
* "name":["百洛安短袖连衣裙2019夏季新款女士时尚显瘦<font color=\"red\">衬衫</font>裙优雅中长A字裙"]}}}
*/
for(Product product:productList){
String name = highlighting.get(product.getId()).get("name").get(0);
//替换
product.setName(name);
}
//获取查询结果记录数
System.out.println("==="+queryResponse.getResults().getNumFound());
System.out.println(productList.size()+"=="+productList);
}
//测试删除
@Test
public void testDelete() throws IOException, SolrServerException {
//client.deleteById("product","200")
String query = "name:爽肤水";
UpdateResponse updateResponse = client.deleteByQuery("product", query);
//提交
client.commit("product");
//0-成功
System.out.println(updateResponse.getStatus());
}
}
五.Spring boot整合
1.整合jar包
2.配置文件
3.代码
注意:实体类必须加如下注解
操作和SorJ一样。。。
六.spring-data-solr
1.依赖
2.配置文件不变
3.接口
分页和高亮
高亮前后缀设置
public Map<String,Object> getProductListByName(String name, Integer pageNow, Integer pageSize){
//获取数据总行数
long count = productRepository.countByName(name);
//分页参数 0表示第一页
PageRequest pageRequest = PageRequest.of(pageNow-1, 3);
//获取高亮结果
HighlightPage<Product> highlightPage = productRepository.findByName(name,pageRequest);
//获取含高亮字段的所有结果
List<HighlightEntry<Product>> highlighted = highlightPage.getHighlighted();
//修改普通字段的值为高亮值
for(HighlightEntry<Product> highlightEntry : highlighted){
//普通结果
Product product = highlightEntry.getEntity();
//高亮结果
List<HighlightEntry.Highlight> highlights = highlightEntry.getHighlights();
//遍历当前对象所有高亮字段
for(HighlightEntry.Highlight highlight : highlights){
//高亮字段名
String fieldName = highlight.getField().getName;
//高亮字段值
String snipplets = highlight.getSnipplets().get(0);
if(fieldName.equals("name")){
product.setName(snipplets);
}
}
}
//获取最终结果
List<Product> productList = highlightPage.getCount();
Map<String, Object> map = new HashMap<String, Object>();
map.put("count",count);
map.put("list",productList);
return map;
}