《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 zhuanlan.zhihu.com/p/78136808 「Carlos Ouyang」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1 Solr简介

1.1 Solr是什么

Solr是一个基于全文检索的企业级应用服务器。可以输入一段文字,通过分词检索数据。它是单独的服务,部署在 tomcat。

1.2 为什么需要Solr

问题:我们已经学过Lucene,为什么还要学习solr?

Carlos Ouyang:Lucene 全文检索插件zhuanlan.zhihu.com图标

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服务器

步骤说明:

  1. 采集数据
  2. 将数据转换成Solr文档
  3. 连接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&amp;useUnicode=true&amp;characterEncoding=utf8&amp;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)导入索引库

文章目录
  1. 1. 1 Solr简介
    1. 1.1. 1.1 Solr是什么
    2. 1.2. 1.2 为什么需要Solr
    3. 1.3. 1.3 Solr目录结构说明
  2. 2. 2 入门示例
    1. 2.1. 2.1 需求
    2. 2.2. 2.2 配置步骤
      1. 2.2.1. 2.2.1 启动 solr
      2. 2.2.2. 2.2.2 配置 solr core
      3. 2.2.3. 2.2.3 创建java程序访问solr服务器
      4. 2.2.4. 2.2.3.1 创建项目,导入 jar 包
      5. 2.2.5. 2.2.3.2 采集数据
        1. 2.2.5.1. (1)创建 pojo
        2. 2.2.5.2. (2)创建 dao
        3. 2.2.5.3. (3)将数据转换成 solr 文档, SolrInputDocument 对象
        4. 2.2.5.4. 2.2.3.3 搜索索引
  3. 3. 3 solr管理控制台
    1. 3.1. 3.1 查询界面说明
    2. 3.2. 3.2 安装DataImport插件
      1. 3.2.1. 3.2.1 Dataimport插件说明
      2. 3.2.2. 3.2.2 安装步骤
      3. 3.2.3. 3.2.3 测试