前言
最近在搭一套微服务环境,其中“帖子模块”需要用到Solr的全文检索和高亮查询,服务搭建完毕后决定将Solr的服务搭建过程和查询简单记录一下。
之前用Lucene实现过类似的功能,Solr也是基于Lucene的,但Solr是面向企业级的搜索服务,功能更强大。
服务搭建
下载软件
前往Solr官网下载,下载链接。
解压并启动
现在Solr已经内置了容器,可以单独运行,无需依赖Tomcat。
./bin/solr start
访问8983端口
http://localhost:8983
看到如下页面表示Solr启动成功。
到这里基本的Solr服务就算搭建完毕了,还是非常简单的。
新建Core
Solr支持多Core,可以把Core看成是MySQL中的一个数据库,它是Solr的索引库,存放着索引数据。
可以在页面上新建,也可以使用如下命令创建:
./bin/solr create -c newCore
新建完Core后,页面上会显示,可以对Core数据做一些增删改查的操作。
中文分词器
Solr内置了很多分词器,虽然也有支持中文的,但是分词效果不是很好。
可以安装其他分词器,用的比较多的就是IK分词器了。
IK分词器下载
https://search.maven.org/search?q=g:com.github.magese
拷贝到以下目录
solr/server/solr-webapp/webapp/WEB-INF/lib
修改配置文件
server/solr/newCore/conf/managed-schema
<!-- IK中文分词器 -->
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
重启Solr,查看分词效果
./bin/solr restart
SpringBoot整合
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
配置文件指明Solr服务地址
spring:
data:
solr:
host: http://localhost:8983/solr/douban
创建需要保存到Solr的实体类
@SolrDocument(solrCoreName = "douban")
@Data
public class PostSolr {
@Field
private String postId;
@Field
private String postText;
@Field
private String postImg;
@Field
private String headImg;
@Field
private String nickName;
@Field
private String remarks;
@Field
private Date createTime;
@Field
private String postTypeText;
@Field
private Integer likeNum;
@Field
private Integer commentNum;
}
Solr配置文件中配置域
server/solr/newCore/conf/managed-schema
<field name="postId" type="string" multiValued="false"/>
<field name="postText" type="text_ik" indexed="true" stored="true" multiValued="false"/>
<field name="postImg" type="string"/>
<field name="headImg" type="string"/>
<field name="nickName" type="string"/>
<field name="remarks" type="string"/>
<field name="createTime" type="pdate"/>
<field name="postTypeText" type="string"/>
<field name="likeNum" type="pint"/>
<field name="commentNum" type="pint"/>
<uniqueKey>postId</uniqueKey>
具体的域配置可以查阅相关资料。
注入SolrClient
与Solr的交互通过SolrClient来进行。
@Autowired
private SolrClient solrClient;
新增文档
装配好PostSolr对象,addBean即可。
solrClient.addBean(postSolr);
查询
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("postText:" + "兴趣");
QueryResponse query = solrClient.query(solrQuery);
List<PostSolr> beans = query.getBeans(PostSolr.class);
solrClient.close();
高亮查询
高亮查询可以使得查询到的关键字高亮显示,类似百度的效果。
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("postText:" + "关键字");
//默认查询的域
solrQuery.set("df","postText");
//开启高亮
solrQuery.set("hl",true);
//高亮的域
solrQuery.set("h1.fl", "postText");
//前缀、后缀 加粗且标红
solrQuery.set("hl.simple.pre", "<b style='color:red'>");
solrQuery.set("hl.simple.post", "</b>");
QueryResponse query = solrClient.query(solrQuery);
Map<String, Map<String, List<String>>> highlighting = query.getHighlighting();
List<PostSolr> beans = query.getBeans(PostSolr.class);
for (PostSolr bean : beans) {
bean.setPostText(highlighting.get(bean.getPostId()).get("postText").get(0));
}
solrClient.close();
删除
根据条件删除文档。
solrClient.deleteByQuery("postId:bf582adafa5f47469914db35f22c9225");
solrClient.commit();
solrClient.close();