作为开发者,我们都知道 Elasticsearch (ES) 很强大,但对服务器内存和CPU也是占用不小。在项目初期或者数据量没那么恐怖的时候,完全可以选择一个更轻量、同样基于 Lucene 的强者:Apache Solr。
今天就从零开始,快速搞定 Solr。
这里以 Linux 为例,Mac 类似,Windows 请下载 zip 包。
bash# 下载 Solr (这里以 8.11.1 为例,请替换为最新版本)
wget https://archive.apache.org/dist/lucene/solr/8.11.1/solr-8.11.1.tgz
# 解压
tar -xzf solr-8.11.1.tgz
# 启动 ( -p 指定端口,-d 以守护进程运行)
cd solr-8.11.1
./bin/solr start -p 8983 -d
访问 http://你的服务器IP:8983/solr,能看到 Admin UI 就成功了!
Solr 中的 Core 类似于 ES 的 Index,是数据的容器。
创建 Core:
bash./bin/solr create_core -c my_core -p 8983
配置字段(managed-schema):
在 Admin UI 找到 my_core -> Schema。这里我们通过 UI 添加字段,底层实际是修改 managed-schema 文件。
id (系统默认已有): type="string",唯一标识。title: 文章标题,需要分词。content: 文章内容,需要分词。create_time: 创建时间,type="pdate"。关键字段类型(FieldType):
text_general: 最常用的文本类型,会分词、转小写,适用于标题、内容等。string: 字符串类型,不分词,适用于 ID、标签、状态等需要精确匹配的字段。pint / plong: 整数/长整数。pfloat / pdouble: 浮点数。pdate: 日期时间类型。默认分词对中文不友好(单字切分)。我们需要 IK Analyzer。
下载 IK Jar 包
去 Maven 仓库搜索 ik-analyzer-solr,下载对应版本的 Jar 文件(如 ik-analyzer-8.5.0.jar)。
部署 Jar 包
将 jar 包放入 server/solr-webapp/webapp/WEB-INF/lib/ 目录下。
配置字段类型
在 managed-schema 中,新增一个 IK 分词字段类型:
xml<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true"/>
</analyzer>
</fieldType>
index 用细粒度分词,保证召回。query 用智能分词,提升准确率。修改字段类型
将 title 和 content 字段的 type 改为我们刚定义的 text_ik。
重启 Solr
./bin/solr restart -p 8983
在 pom.xml 中添加依赖:
xml<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
在 application.yml 中配置:
yamlspring:
data:
solr:
host: http://localhost:8983/solr # 你的 Solr 地址
创建一个文档实体类:
javaimport org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;
@SolrDocument(collection = "my_core") // 指定 Core 名
public class Article {
@Id
@Indexed
private String id;
@Indexed(type = "text_ik") // 使用 IK 分词的字段
private String title;
@Indexed(type = "text_ik")
private String content;
@Indexed(type = "pdate")
private Date createTime;
// getter/setter 省略
}
创建 Repository:
javapublic interface SolrArticleRepository extends SolrCrudRepository<Article, String> {
// Spring Data 会自动实现
List<Article> findByTitleOrContent(String title, String content);
// 更复杂的查询可以使用 @Query 注解
@Query("title:*?0* OR content:*?0*")
List<Article> findByKeyword(String keyword);
}
在 Service 中注入 Repository 即可操作。
java@Service
public class SearchService {
@Autowired
private SolrArticleRepository solrRepo;
// 新增或更新
public void save(Article article) {
if(article.getId() == null) {
article.setId(UUID.randomUUID().toString());
}
article.setCreateTime(new Date());
solrRepo.save(article);
}
// 按 ID 查询
public Optional<Article> findById(String id) {
return solrRepo.findById(id);
}
// 关键词搜索
public List<Article> search(String keyword) {
return solrRepo.findByKeyword(keyword);
}
// 按 ID 删除
public void delete(String id) {
solrRepo.deleteById(id);
}
}
总结
一套流程下来,你会发现 Solr 的 Admin UI 对开发者非常友好,配置和调试都很直观。对于大多数中小规模的搜索场景,Solr 在性能上和 ES 相差无几,但资源消耗却友好得多。
如果你的项目正面临资源瓶颈,又想快速引入一个强大的搜索功能,Solr 绝对是一个值得你花半天时间尝试的优秀选择。
行动路线:
本文作者:zjx171
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!