Solr 01:用Intellij IDEA搭建服务

solr可以使用自带的jetty启动,但为了后续开发和调试的方便,还是采用IDEA+tomcat的方式搭建环境。文中主要讲述怎样用Intellij IDEA搭建搜索引擎服务。

软件准备

  • Intellij IDEA 2017.1.3
  • tomcat-8.0.22
  • solr-6.5.1
  • mysql-connector-java-5.1.42-bin.jar - mysql驱动
  • ikanalyzer-solr - 分词匹配,适用于solr-6.5
  • pinyin4j-2.5.0.jar - 拼音检索
  • pinyinAnalyzer4.3.1.jar - 拼音检索

创建工程

新建一个文件夹 solr,路径为 /Users/tyrival/Documents/Workspace/solr,进行如下操作:

1
2
3
4
5
6
7
* solr-6.5.1\server\solr-webapp\webapp 下所有内容复制到 solr 中
* solr-6.5.1\server\lib 中所有jar复制到 solr\WEB-INF\lib 中
* solr-6.5.1\server\lib\ext 中所有jar复制到 solr\WEB-INF\lib 中
* 新建 solr\src\main\java 文件夹
* solr-6.5.1\server\resources\log4j.properties 复制到 solr\src\main\java 中
* 新建 solr\solrhome 文件夹
* solr-6.5.1\server\solr 中所有文件复制到 solr\solrhome 中

Solrhome

修改 solr\WEB-INF\web.xml 中的 env-entry-value 值,修改为项目中solrhome的绝对路径

1
2
3
4
5
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>/Users/tyrival/Documents/Workspace/solr/solrhome</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

配置IDEA

打开Project Structure(Command + ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Project
* SDK -> java 1.8

Modules
* 选中目录树上的solr
* Sources标签,设置src\main\java为Sources类型
* Paths标签,设置Output path:/Users/tyrival/Documents/Workspace/solr/WEB-INF/classes,勾选Exclude output paths
* 选中目录树上的Web,如果没有,可以点上面的加号新建一个Web,然后点右下角出现的Fix按钮
* 勾选右下方的Source Roots

Libraries
* 点顶部的+号,选择 solr\WEB-INF\lib 文件夹

Artifacts
* 点+号,选择Web Application:Exploded => From Modules

OK

打开Run/Debug Configurations,配置tomcat

1
2
3
4
5
6
7
8
9
10
11
* 点左上角+号,选择Tomcat Server => Local
* 输入Name

Server
* Open browser中,勾选After launch,输入默认打开路径为 http://localhost:8080/solr/index.html

Deployment
* 点面板中部的+号,选择Artifact => 第3步创建的solr:Web exploded
* Application context改为 /solr

OK

启动

点运行,浏览器打开http://localhost:8080/solr/index.html,服务搭建成功。

配置core

  • 新建 solr\solrhome\my_solr 文件夹
  • solr-6.5.1\example\example-DIH\solr\solr 中所有文件复制到刚创建的 my_solr 中
  • 将mysql驱动 mysql-connector-java-5.1.42-bin.jar 复制到 solr/WEB-INF/lib 中,
  • 修改 my_solr\conf\solr-data-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<!-- 数据库连接 -->
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://10.211.55.82:3306/test"
user="root"
password="root"/>

<!-- 数据表映射 -->
<document name="solr_mysql_test">
<entity name="solrTest"
pk="id"
query="select * from solrTest"
deltaImportQuery="select * from solrTest where id = '${dih.delta.id}'"
deltaQuery="select id from solrTest where updateTime > '${dataimporter.last_index_time}'"/>

<field column="id" name="id"/>
<field column="context" name="context"/>
<field column="updateTime" name="updateTime"/>
<field column="sort" name="sort"/>
</document>
</dataConfig>
  • 修改 my_solr\conf\managed-schema,在schema标签下添加
1
2
3
4
<!-- 这里没有添加field = id,因为managed-schema中默认已经存在了 -->
<field name="context" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="updateTime" type="date" indexed="true" stored="true" multiValued="false"/>
<field name="sort" type="int" indexed="true" stored="true" multiValued="false"/>

这里可以将managed-schema复制为schema.xml,然后修改内容,这样对IDEA来说更清晰。

MySql

1
2
3
4
5
6
7
CREATE TABLE `solrTest` (  
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`context` varchar(255) DEFAULT NULL COMMENT 'context',
`updateTime` datetime DEFAULT NULL COMMENT 'updateTime',
`sort` int(11) DEFAULT '1' COMMENT '排序',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

插入几条测试数据。

导入插件

  • solr-6.5.1\dist 下的 solr-dataimporthandler-6.0.0.jar 和 solr-dataimporthandler-extras-6.0.0.jar 复制到 solr\WEB-INF\lib 中

数据导入

1
2
3
Indexing completed. Added/Updated: 3 documents. Deleted 0 documents. (Duration: 01s)
Requests: 1 1/s, Fetched: 3 3/s, Skipped: 0 , Processed: 3 3/s
Started: about 8 hours ago
  • 展开Raw Status-Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"responseHeader": {
"status": 0,
"QTime": 0
},
"initArgs": [
"defaults",
[
"config",
"solr-data-config.xml"
]
],
"command": "status",
"status": "idle",
"importResponse": "",
"statusMessages": {
"Total Requests made to DataSource": "1",
"Total Rows Fetched": "3",
"Total Documents Processed": "3",
"Total Documents Skipped": "0",
"Full Dump Started": "2017-05-27 14:47:32",
"": "Indexing completed. Added/Updated: 3 documents. Deleted 0 documents.",
"Committed": "2017-05-27 14:47:33",
"Time taken": "0:0:0.602"
}
}
  • 如果导入失败,可以打开Logging查看错误日志

  • 打开Query,点击Execute Query可以查看到导入的数据

分词、停止词、扩展词

1
2
3
* 复制 IKAnalyze-solr 中的 ik-analyzer-solr5-5.x.jar 和 solr-analyzer-ik-5.1.0.jar 到 solr\WEB-INF\lib 中
* 复制 IKAnalyze-solr 中的 ext.dic、stopword.dic、IKAnalyzer.cfg.xml 到 solr\src\main\java 中
* 修改 IKAnalyzer.cfg.xml
1
2
3
4
5
6
7
8
9
<?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">ext.dic;</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>
  • 修改 solr\solrhome\my_solr\conf\managed-schema,注册分词插件
1
2
3
4
5
6
7
8
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
</analyzer>
</fieldType>
  • 修改 solr\solrhome\my_solr\conf\managed-schema 中的 field=context,启用分词查询
1
<field name="context" type="text_ik" indexed="true" stored="true" multiValued="false"/>
  • 在浏览器左侧进入my_solr => Query, 修改 q 为 context:关键词,就可以按照关键字进行分词匹配,查出结果。
  • 停止词表示在查询中需要忽略的词,比如语气词“啊”、“呀”或者“的”、“得”等,可在stopword.dic中配置
  • 扩展词表示部分非常用词汇、专业词汇、新造词,例如:“炉石传说”、“吉安娜”等,可在ext.dic重配置

拼音检索

  • 复制 pinyin4j-2.5.0.jar、pinyinAnalyzer.jar 到 solr/WEB-INF/lib 中

  • 在 solr\solrhome\my_solr\conf\managed-schema 的 schema 标签中增加:

1
2
3
4
5
6
7
8
9
10
11
12
<fieldType name="text_pinyin" class="solr.TextField" positionIncrementGap="0">
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory"/>
<filter class="com.shentong.search.analyzers.PinyinTransformTokenFilterFactory" minTermLenght="2" />
<filter class="com.shentong.search.analyzers.PinyinNGramTokenFilterFactory" minGram="1" maxGram="20" />
</analyzer>
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory"/>
<filter class="com.shentong.search.analyzers.PinyinTransformTokenFilterFactory" minTermLenght="2" />
<filter class="com.shentong.search.analyzers.PinyinNGramTokenFilterFactory" minGram="1" maxGram="20" />
</analyzer>
</fieldType>
  • 在web端,Analysis中校验拼音检索

同义词

  • 在 solr\solrhome\my_solr\conf\managed-schema 的 schema 标签中增加:
1
2
3
4
5
6
7
8
9
10
11
<fieldType name="text_syn" class="solr.TextField">
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
  • 修改 solr\solrhome\my_solr\conf\managed-schema 中的 field=context,启用同义词查询
1
<field name="context" type="text_syn" indexed="true" stored="true" multiValued="false"/>
  • 在 solr\solrhome\my_solr\conf\synonyms.txt 中增加同义词映射:
1
2
3
4
5
# 格式1,箭头表示映射
测试 => test

# 格式2,用英文逗号隔开同义词组
测试,test,tst
  • 在web端,Analysis中校验同义词检索
分享到