什么是Solr
Solr是一个独立的企业级搜索应用服务器,它对外提供API接口。
- 用户通过HTTP的POST请求,向Solr服务器提交一定格式的XML或JSON文件,Solr服务器解析文件后,根据具体需求对索引库执行增删改操作;
- 用户通过HTTP的GET请求,向Solr服务器发送搜索请求,并得到XML/JSON格式的返回结果。
Solr可以独立运行在Jetty、Tomcat等Servlet容器中。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Solr配置
下载最新版本的Solr 8.7 ,解压后得到如下目录:
启动Solr服务器
.\bin\solr.cmd start
关闭Solr服务器
.\bin\solr.cmd stop -all
访问本地服务 http://localhost:8983/solr/#/
创建新的SolrCore
SolrCore类似于传统MySql中的数据库概念。
- 在\server\solr下新建文件夹lwtx_demo
- 将\server\solr\configsets\_default\conf下文件拷贝到\server\solr\lwtx_demo下
- 在Core Admin里新建一个 Add Core
至此,在Core Selector里会出现新的lwtx_demo,选择这个SolrCore,后续的操作都会在这个SolrCore里进行。
如何同步MySql数据
将mysql驱动、solr-dataimporthandler-8.7.0.jar、solr-dataimporthandler-extras-8.7.0.jar 拷贝至\server\solr-webapp\webapp\WEB-INF\lib
在solrconfig.xml文件中,加入dataimport的Handle
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">db-data-config.xml</str>
</lst>
</requestHandler>
在\server\solr\lwtx_demo下新建配置文件db-data-config.xml
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/dev-tesing-rds?serverTimezone=UTC"
user="demo" password="123456"/>
<document>
<entity name="demo" query="SELECT id,name from demo">
<field column="id" name="solr_id" />
<field column="name" name="solr_name" />
</entity>
</document>
</dataConfig>
在managed-schema文件中新增field
<field name="solr_id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="solr_name" type="string" indexed="true" stored="true" />
至此可以实现import功能
Java代码实战
Solrj是访问Solr服务器的Java客户端,提供索引和搜索的方法。
依赖包
<!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>8.7.0</version>
</dependency>
导入数据
String solrUrl = "http://localhost:8983/solr/lwtx_demo/";
//创建Solr的客户端连接对象
SolrClient solrServer = new HttpSolrClient.Builder(solrUrl).build();
// TODO 模拟初始化数据
List<Product> productList = new ArrayList<>();
// 创建文档
List<SolrInputDocument> docs = new ArrayList<>();
SolrInputDocument doc;
for (Product product : productList) {
doc = new SolrInputDocument();
doc.addField("id", product.getPid());
doc.addField("product_name", product.getName());
doc.addField("product_catalog_name", product.getCatalog_name());
doc.addField("product_price", product.getPrice());
doc.addField("product_description", product.getDescription());
doc.addField("product_picture", product.getPicture());
docs.add(doc);
}
// 先清空索引库
solrServer.deleteByQuery("*:*");
// 再索引文档
solrServer.add(docs);
solrServer.commit();
查询数据
String solrUrl = "http://localhost:8983/solr/lwtx_demo/";
//创建Solr的客户端连接对象
SolrClient solrServer = new HttpSolrClient.Builder(solrUrl).build();
// 创建SolrQuery对象
SolrQuery solrQuery = new SolrQuery();
// 设置查询关键词
if (StringUtils.hasLength(queryString)) {
solrQuery.setQuery(queryString);
} else {
solrQuery.setQuery("*:*");
}
// 设置默认域
solrQuery.set("df", "product_keywords");
// 设置商品类名过滤条件
// 设置商品分类名称
if (StringUtils.hasLength(catalog_name)) {
catalog_name = "product_catalog_name:" + catalog_name;
}
// 设置商品价格
if (StringUtils.hasLength(price)) {
String[] sp = price.split("-");
if (sp != null && sp.length == 2) {
price = "product_price:[" + sp[0] + " TO " + sp[1] + "]";
}
}
solrQuery.setFilterQueries(catalog_name, price);
// 商品排序,如果是1,正序排序,如果是其他,则倒序排序
if ("1".equals(sort)) {
solrQuery.setSort("product_price", ORDER.asc);
} else {
solrQuery.setSort("product_price", ORDER.desc);
}
// 设置分页
if (page == null) {
page = 1;
}
solrQuery.setStart((page - 1) * 20);
solrQuery.setRows(20);
// 设置高亮
solrQuery.setHighlight(true);
solrQuery.addHighlightField("product_name");
solrQuery.setHighlightSimplePre("<font color='red'>");
solrQuery.setHighlightSimplePost("</font>");
// 查询数据
QueryResponse response = solrServer.query(solrQuery);
// 获取查询总数
SolrDocumentList results = response.getResults();
long total = results.getNumFound();
// 获取高亮数据
Map<String, Map<String, List<String>>> map = response.getHighlighting();
// 解析结果集,存放到Product中
List<Product> products = new ArrayList<>();
for (SolrDocument solrDocument : results) {
Product product = new Product();
// 商品id
product.setPid(solrDocument.get("id").toString());
// 商品标题,设置高亮
List<String> list = map.get(solrDocument.get("id")).get("product_name");
if (list != null && list.size() > 0) {
product.setName(list.get(0));
} else {
product.setName(solrDocument.get("product_name").toString());
}
// 商品价格
product.setPrice(solrDocument.get("product_price").toString());
// 商品图片
product.setPicture(solrDocument.get("product_picture").toString());
products.add(product);
}
// 封装返回对象
Result result = new Result();
result.setCurPage(page);
result.setRecordCount(total);
result.setProductList(products);
// 总页数计算公式(total+rows-1)/rows
result.setPageCount((int) (total + 20 - 1) / 20);
return result;