Solr 8.2 使用指南
1 solr简介
1.1 solr是什么
solr是一个基于全文检索的企业级应用服务器。可以输入一段文字,通过分词检索数据。它是单独的服务,部署在 tomcat。
1.2 为什么需要solr
问题:我们已经学过lucene,为什么还要学习solr?
lucene是一个工具包,不能单独运行,需要导入到java代码中。solr可以独立运行在tomcat容器中,通过http协议,以接口的方式对外提供服务,java代码只需要专注于业务的处理就可以。
1.3 solr目录结构说明
- bin:solr的运行脚本
- contrib:solr的一些扩展jar包,用于增强solr的功能
- dist:该目录包含build过程中产生的jar文件,以及相关的依赖文件
- example:solr工程的例子目录
- licenses:solr相关的一些许可信息
2 入门示例
2.1 需求
将数据库的数据导入 solr 中,实现查询功能
2.2 配置步骤
2.2.1 启动 solr
进入 solr 解压路径下的 bin 目录,按 shift + 鼠标右键,选择在此次打开命令行工具
输入命令: .\solr start
启动 solr 服务
使用浏览器访问 localhost:8983 即可进入后台控制页面。
2.2.2 配置 solr core
继续使用命令工具创建一个 core,core 就相当于一个 solr 的项目实例。
命令:solr create -c <core_name>
成功创建后,可以在 solr-8.2.0/server/solr/<core_name>
目录下看到自动生成的默认配置文件
创建完成后,重新进入后台控制页面,可以查看到新建的 core
2.2.3 创建java程序访问solr服务器
步骤说明:
- 采集数据
- 将数据转换成solr文档
- 连接solr服务器,将文档写入索引库
2.2.3.1 创建项目,导入 jar 包
需要导入的包有:
- solrj 核心包:
solr-8.2.0\dist\solr-core-8.2.0.jar
- solrj 依赖包:
solr-8.2.0\dist\solrj-lib\
目录下的所有包 - jdbc 驱动包:根据数据库版本而定,我这里拷的是 mysql 8 的驱动包
项目结构:
2.2.3.2 采集数据
需求采集的字段说明:
- 参与搜索的字段:名称、价格、商品类别、描述信息
- 参与结果展示的字段:商品id、图片
(1)创建 pojo
public class product { private integer pid; private string name; private string categoryname; private double price; private string description; private string picture; //省略 getter、setter、constructor、tostring }
(2)创建 dao
public class productdao { public list<product> listall() { list<product> products = new arraylist<>(); //获取数据库连接 connection conn = jdbcutils.getconnection(); string sql = "select * from `products`"; statement statement = null; resultset resultset = null; try { //创建 statement statement = conn.createstatement(); //执行 sql 语句 resultset = statement.executequery(sql); //循环操作结果集 while (resultset.next()) { products.add(new product(resultset.getint("pid"), resultset.getstring("name"), resultset.getstring("category_name"), resultset.getdouble("price"), resultset.getstring("description"), resultset.getstring("picture"))); } } catch (sqlexception e) { e.printstacktrace(); } finally { //关闭资源 if (null != resultset) { try { resultset.close(); } catch (sqlexception e) { e.printstacktrace(); } finally { if (null != statement) { try { statement.close(); } catch (sqlexception e) { e.printstacktrace(); } finally { if (null != conn) { try { conn.close(); } catch (sqlexception e) { e.printstacktrace(); } } } } } } } return products; } }
(3)将数据转换成 solr 文档, solrinputdocument 对象
solr是通过一个配置文件managed-schema,事先定义域的信息的,需要先定义再使用。
配置文件里面事先定义好了各种 <dynamicfield>
,能够根据命名动态的指定域的类型,也就是 type 属性。
而域的类型也在此做了定义,用的是 <fieldtype>
标签。(可对比 lucene 理解)
其中,text-general 指定了分词器,以及一些拓展配置文件
我们可以根据需要,按照上述例子,手动的声明几个域,并使用中文分词。先将 lucene 中的 smartchineseanalyzer 的 jar 包拷入文件夹中
再修改 managed-schema 配置文件,添加以下内容
重启服务器后,可以看到效果
为 dao 添加 getdocuments 方法
public list<solrinputdocument> getdocuments(list<product> products) { list<solrinputdocument> documents = new arraylist<>(); products.foreach(product -> { solrinputdocument document = new solrinputdocument(); document.addfield("id", product.getpid());//对应solr的uniquekey document.addfield("product_name", product.getname()); document.addfield("product_price", product.getprice()); document.addfield("product_category_name", product.getcategoryname()); document.addfield("product_picture", product.getpicture()); document.addfield("product_description", product.getdescription()); documents.add(document); }); return documents; }
创建索引库
@test public void createindex() { //1.创建 httpsolrclient.builder 对象,通过它创建客户端通信 httpsolrclient.builder builder = new httpsolrclient.builder("http://localhost:8983/solr"); httpsolrclient solrclient = builder.build(); //2.通过 client 将 document 加入索引库 productdao dao = new productdao(); try { //参数1是 solr core 的名字 solrclient.add("product", dao.getdocuments(dao.listall())); solrclient.commit("product"); system.out.println("创建索引库完成"); } catch (solrserverexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } }
导入成功后可以在后天控制页面看到结果
2.2.3.3 搜索索引
@test public void querytest() { //1.创建 httpsolrclient.builder 对象,通过它创建客户端通信 httpsolrclient.builder builder = new httpsolrclient.builder("http://localhost:8983/solr"); httpsolrclient solrclient = builder.build(); //2.创建一个map封装搜索条件 map<string, string> querymap = new hashmap<>(); querymap.put("q","音乐盒");//关键字 querymap.put("df", "product_name");//默认搜索域 //querymap.put("sort","id asc");//结果以 id 升序排列,默认以关联度排序 querymap.put("rows","20");//默认只有十条 //3.使用map创建 mapsolrparams 对象 solrparams solrparams = new mapsolrparams(querymap); try { //4.使用客户端进行查询 queryresponse response = solrclient.query("product", solrparams); //5.提取结果 solrdocumentlist documents = response.getresults(); system.out.println("一共查询到:" + documents.getnumfound() + "条结果"); //6.循环输出 documents.foreach(document ->{ system.out.println("编号" + document.get("id") + ":" + document.get("product_name")); }); } catch (solrserverexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } }
3 solr管理控制台
3.1 查询界面说明
可以根据查询界面各个关键字,设置上述代码 querymap,实现复杂的查询功能。key 对应的就是关键字,value 就是输入框内的值。
3.2 安装dataimport插件
3.2.1 dataimport插件说明
使用该插件后,可以在管理界面直接从数据库导入数据到索引库。(即:一个插件解决入门示例中,创建索引的全部操作)
3.2.2 安装步骤
(1)拷贝相关 jar 包到文件夹
(2)修改 \solr-8.2.0\server\solr\product\conf\solrconfig.xml
文件,增加以下代码
(3)在 \solr-8.2.0\server\solr\product\conf\
目录下新建 dihconfig.xml 文件,并编写以下内容
<dataconfig> <datasource type="jdbcdatasource" driver="com.mysql.cj.jdbc.driver" url="jdbc:mysql://localhost:3306/solr?servertimezone=utc&useunicode=true&characterencoding=utf8&usessl=false" user="root" password="password" /> <document> <entity name="product" query="select * from products"> <field column="pid" name="id"/> <field column="name" name="product_name"/> <field column="price" name="product_price"/> <field column="category_name" name="product_category_name"/> <field column="description" name="product_description"/> <field column="picture" name="product_picture"/> </entity> </document> </dataconfig>
(4)重启 solr 服务
3.2.3 测试
(1) 清空索引库
(2)导入索引库