一.准备工作
1. 环境准备:
1.1 centos 6.5/mac os 10.12.6
1.2 solr6.6.0:http://archive.apache.org/dist/lucene/solr/6.6.0/solr-6.6.0.tgz
1.3 IK_Analyzer: https://github.com/SetGeek/ck/blob/master/IK-Analyzer分词器/ik-analyzer-solr6.x.jar
1.4 mysql驱动:https://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.44.zip
2. 假定一个需求:现在需要索引商品信息,以支撑前台商品展示页面的搜索。
- 数据库中的表有商品分类表和商品详情表
-- 商品表:
DROP TABLE IF EXISTS `rd_product`;
CREATE TABLE `rd_product` (
`id` varchar(32) NOT NULL COMMENT '商品编号',
`p_name` varchar(100) NOT NULL COMMENT '商品名称',
`p_price` decimal(20,2) NOT NULL COMMENT '商品单价',
`p_amount` int(10) NOT NULL COMMENT '商品数量',
`p_desc` varchar(1000) DEFAULT NULL COMMENT '商品描述',
`p_type` varchar(32) DEFAULT NULL COMMENT '商品类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 商品类型表:
DROP TABLE IF EXISTS `rd_type`;
CREATE TABLE `rd_type` (
`id` varchar(32) NOT NULL COMMENT '类型编号',
`t_name` varchar(100) NOT NULL COMMENT '类型名称',
`t_desc` varchar(1000) DEFAULT NULL COMMENT '类型详情',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二. 搭建standalone模式(单机)的solr服务
1. 安装并启动服务。
解压solr-6.6.0.tgz压缩包,在解压后的文件夹下,使用自带的jetty容器启动solr服务,默认端口为8983,也可以自定义端口启动。
默认启动的命令:
bin/solr start
指定端口启动(8080)的命令:
bin/solr start -p 8080
服务停止命令:
bin/solr stop
2. 查看管理界面。
在浏览器中访问http://localhost:8983/solr
,进入solr的管理界面,
3. 创建索引库。
索引存放在索引库中,此时solr中是没有索引库的,需要创建一个索引库,并命名为RD-Core
创建索引库的命令:
bin/solr create -c RD-Core
删除索引库的命令:bin/solr delete -c RD-Core
4. 配置中文分词器
如果不需要自定义敏感词汇和行业名词,可以使用solr自带的分词器,否则需要使用IK-Analyzer
、paoding
等分词器。
4.1 配置solr自带的分词器(选择性配置,也可以都配置上)
4.1.1 引入分词器的jar文件:在server/solr/RD-Product/conf/solrconfig.xml
中配置如下信息。
<!-- 引入"contrib/rd-lib/"下所有jar文件 -->
<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs/" regex=".*\.jar" />
4.1.2 添加一个中文分词的字段类型(filedType):在solr中,字段类型(fieldType)相当于数据库中的字段类型(int
、varchar
…),在server/solr/RD-Product/conf/managed-schema
中配置如下内容
<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">
<!-- 索引时的分词器 -->
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
</analyzer>
<!-- 查询时的分词器 -->
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
</analyzer>
</fieldType>
4.2 配置IKAnalyzer分词器
4.2.1 添加分词器的jar文件:在contrib
下新建文件夹rd-lib
,并将ik-analyzer-solr6.x.jar
拷贝进来,这个文件夹用来存放第三方jar文件,后面做数据导入时候,用到的mysql数据库驱动也放到这个文件夹下。
4.2.2 引入分词器的jar文件:在server/solr/RD-Product/conf/solrconfig.xml
中配置如下信息,将rd-lib
这个文件夹下的所有jar包引入到服务中。
<!-- 引入"contrib/rd-lib/"下所有jar文件 -->
<lib dir="${solr.install.dir:../../../..}/contrib/rd-lib/" regex=".*\.jar" />
4.2.3 添加一个中文分词的字段类型(filedType):在server/solr/RD-Product/conf/managed-schema
中配置如下内容
<!--中文分词器IK Analyzer-->
<fieldType name="text_ik" class="solr.TextField">
<!--索引时候的分词器-->
<analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<!--查询时候的分词器-->
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" isMaxWordLength="false" useSmart="false"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
4.2.4 自定义敏感词汇与行业专属词汇(如果不需要,可以跳过)
在server/solr-webapp/webapp/WEB-INF/
下新建一个文件夹classes
,并新建文件IKAnalyzer.cfg.xml
,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典,'/'表示项目的根路径,多个文件用';'分隔 -->
<entry key="ext_dict">/ext1.txt;/ext2.txt;</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<!-- <entry key="ext_stopwords">stopwords.txt;</entry> -->
</properties>
5. 添加需要索引的字段
我们需要索引商品的名称、价格、数量、商品描述、商品类型和商品类型描述,则在文件server/solr/RD-Product/conf/managed-schema
中配置如下字段,其中的name是自定义的,不需要与数据库保持一致,type可以是solr内置的数据类型,也可以是上面配置的中文分析器的类型,如果字段包含中文,强烈建议配置为text_smartcn
或text_ik
。
<!-- 商品信息 -->
<field name="p_name" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_price" type="float" indexed="true" stored="true" multiValued="true"/>
<field name="p_amount" type="int" indexed="true" stored="true" multiValued="true"/>
<field name="p_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_type_name" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="t_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
6. 配置数据库连接(如果不需要从数据库导入数据,该步骤可以省略)
6.1 引入数据导入的jar包,并添加数据导入处理器,在server/solr/RD-Product/conf/solrconfig.xml
中配置
<!-- 导入文件夹dist下所有的jar -->
<lib dir="${solr.install.dir:../../../..}/dist/" regex=".*\.jar" />
<!--数据库导入索引的配置文件 -->
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
6.2 在server/solr/RD-Product/conf/
中创建data-config.xml
,并在其中配置数据库与索引库的连接信息。
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<!-- 数据库驱动及数据库信息,数据库:rd_mall,用户名:root,密码为空 -->
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/rd_mall" user="root" password="" batchSize="-1" />
<document>
<entity name="rd_product" query="SELECT p.id AS 'pID',p.p_name AS 'pName',p.p_price AS 'pPrice',p.p_amount AS 'pAmount',p.p_desc AS 'pDesc',t.t_name AS 'pType',t.t_desc AS 't_desc' FROM rd_product p,rd_type t WHERE p.p_type=t.id">
<!--column的id是数据库的id,name的id是managed_schema里面的id,id是必须,并且唯一的-->
<field column="pID" name="id" />
<!--column的pName是数据库的p_name字段,name的p_name是schema-managed中的字段,下面配置同理-->
<field name="p_name" column="pName"/>
<field name="p_price" column="pPrice"/>
<field name="p_amount" column="pAmount"/>
<field name="p_desc" column="pDesc"/>
<field name="p_type_name" column="pType"/>
<field name="t_desc" column="tDesc"/>
</entity>
</document>
</dataConfig>
6.3 重启服务后,使用以下命令导入数据,至此,单机版的solr服务搭建完毕。
重启服务:
bin/solr restart
导入数据:
curl http://localhost:8983/solr/RD-Product/dataimport\?command\=full-import
删除所有数据:
bin/post -c RD-Product -d "<delete><query>*:*</query></delete>"
删除指定id的数据:
bin/post -c RD-Product -d "<delete><id>p001</id></delete>"
二. SolrJ的使用示例
1.新建一个maven项目,pom.xml如下配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sgcc.gdt.search</groupId>
<artifactId>rd_solr_demo</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.增(改)、删、查及数据库导入数据的使用
public class SearchServer {
/** solr服务客户端 */
private SolrClient solrClient;
/** solr服务的地址 */
private String solrURL = "http://127.0.0.1:8983/solr";
/** solr索引库的名称 */
private String coreName = "RD-Product";
/**
* 获取solr服务的客户端
*/
@Before
public void init() {
solrClient = new HttpSolrClient("http://127.0.0.1:8983/solr");
}
/**
* 关闭solr服务
*/
@After
public void destroy() throws IOException {
if (solrClient != null) {
solrClient.close();
}
}
/**
* 查询示例
*/
@Test
public void queryTest() throws IOException, SolrServerException {
//查询条件
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("*:*");
//查询方法
QueryResponse response = solrClient.query(coreName, solrQuery);
SolrDocumentList results = response.getResults();
System.out.println("查询结果:" + response);
}
/**
* 添加索引
*/
@Test
public void add() throws IOException, SolrServerException {
//构造索引文档
SolrInputDocument document = new SolrInputDocument();
String id = UUID.randomUUID().toString().replaceAll("-", "");
document.setField("id", id);
document.setField("p_name", "神州笔记本电脑");
document.setField("p_price", 1234f);
document.setField("p_amount", 100);
document.setField("p_type_name", "电脑");
//添加索引文档
solrClient.add(coreName, document);
solrClient.commit(coreName);
System.out.println("添加成功!");
}
/**
* 删除索引
*/
@Test
public void delete() throws IOException, SolrServerException {
solrClient.deleteByQuery(coreName, "*:*");
System.out.println("删除成功!");
}
/**
* 从数据库导入索引
*/
@Test
public void dataImportTest() throws IOException {
String path1 = "http://localhost:8983/solr/RD-Product/dataimport?command=full-import";
RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
HttpGet httpGet = new HttpGet(path1);
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == HttpStatus.SC_OK){
httpGet.abort();
System.out.println("导入数据成功!");
}
}
}
本示例中出现的问题,欢迎指正,共同学习!
GitHub地址:https://github.com/SetGeek/ck.git
本人邮箱: yangchaokai@foxmail.com