简介
大部分项目都会涉及模糊搜索功能,而实现模糊搜索一般分为两个派系:
- like简约派系
- 搜索引擎派系
对于较为大型的项目来说,使用Solr、ES或者Milvus之类的引擎是比较流行的选择了(效果只能说优秀),而对于中小型项目,如果考虑这些较为重型的引擎,就意味着开发成本和运维成本
而一个简单的项目,特别是很多后台管理系统,模糊搜索仅仅是一个附带的功能(并非核心功能),所以我并不花太多时间去集成一个重量级的搜索引擎,此时为了方便就会选择like系列(偷懒的时候就这么干)
但是like也存在一些问题:
- 数据量较大时,性能会急剧下降
- 搜索词必须完整存在数据库中,只能进行左右模糊匹配
- 如果使用左右两边模糊就会导致索引失效
终究是为一时的懒惰付出了代价…
但是…终究是想抽个空喝一口茶,顺便摸个鱼,如此我只能祭出SimSearch:一个轻量级的springboot项目索引构建工具,实现快速模糊搜索,相比于搜索引擎派系,这是一种轻量级的实现方式
索引测试
使用100万行中文 进行模糊搜索测试
i7 16g
存储模式(saver) | 平均耗时 | 最大耗时 | 最小耗时 |
---|---|---|---|
nio-fs(nio文件模式) | 45.93ms | 144.5ms | 15.04ms |
base-fs(常规文件系统) | 25.93ms | 97.32ms | 12.24ms |
memory-fs(nmap文件模式) | 23.75ms | 114.12ms | 8.4ms |
memory(内存模式) | 11.56ms | 42.35ms | 7.04ms |
使用1000万行类似的中文创建索引后进行模糊搜索测试
存储模式(saver) | 平均耗时 | 最大耗时 | 最小耗时 |
---|---|---|---|
nio-fs(nio文件模式) | 55.33ms | 151.5ms | 20.65ms |
base-fs(常规文件系统) | 63.02ms | 102.73ms | 15.34ms |
memory-fs(nmap文件模式) | 51.44ms | 180.38ms | 7.15ms |
memory(内存模式) | 12.98ms | 50.26ms | 8.04ms |
相对于文件系统,内存性能最好的无疑的,前提是内存有余,或者数据量不是很过分
测试的文本相对来说较短,如果是长文本,理论上上来说性能会下降一些
另外,以上结果仅仅作为一个参考
使用教程
可以有两种使用模式:注解和工具类,最完整的使用教程可以看源码的demo项目
先来说说注解使用,在原有的实体类和业务代码上标几个注解即可
1. 引入依赖
<dependency>
<groupId>cn.langpy</groupId>
<artifactId>simsearch</artifactId>
<version>2.0.0</version>
</dependency>
使用了@Aspect注解,未引入的自行引入,如aspectj或者spring-boot-starter-aop
2. 配置信息
在application.properties中配置
#索引存储器 默认为内存 [memory,memory-fs,base-fs,nio-fs]
#内存富裕的情况下使用memory,如果是百万以上数据量选用fs系列
sim-search.saver=memory
#索引位置,saver!=memory时需配置
sim-search.dir=/data/indexlocation
#创建索引的核心线程数量,根据cpu自行决定,可不填,默认为5
sim-search.thread-core-size=5
#创建索引的最大线程数量,根据cpu自行决定,可不填,默认为200
sim-search.thread-max-size=10
#创建索引的线程队列容量,自行决定,可不填,默认为200000
sim-search.thread-queue-size=200000
#重启时是否要对之前的索引进行删除,默认为false
sim-search.index.init=true
#最大返回的搜索结果数量
sim-search.result.size=50
3. 在需要创建索引的实体上标注需要创建索引的字段
import cn.langpy.simsearch.annotation.IndexColumn;
import cn.langpy.simsearch.annotation.IndexId;
public class Student {
/*索引唯一id 必须*/
@IndexId
private String id;
/*需要创建索引的字段:用来模糊搜索*/
@IndexColumn
private String studentName;
@IndexColumn
private String schoolName;
private String age;
}
4. 在需要创建索引的方法上加上创建索引的注解
import cn.langpy.simsearch.annotation.CreateIndex;
import cn.langpy.simsearch.annotation.DeleteIndex;
import cn.langpy.simsearch.annotation.SearchIndex;
@Service
public class StudentServiceImpl implements StudentService {
/*加上@CreateIndex后 异步创建索引,不影响正常业务的保存逻辑 indexParam:需要创建索引的参数*/
/*该注解包含了更新操作 有则更新 无则创建*/
@CreateIndex(indexParam = "student")
public boolean insert(Student student){
/*业务逻辑*/
}
}
5. 在需要删除索引的方法上加上删除索引的注解
@Service
public class StudentServiceImpl implements StudentService {
/*加上@DeleteIndex后 异步删除索引,不影响正常业务的删除逻辑 indexParam:需要删除索引的参数*/
@DeleteIndex(indexParam = "student")
public boolean delete(Student student){
/*业务逻辑*/
}
}
6. 搜索的时候自定义一个空的方法,加上注解即可
@Service
public class StudentServiceImpl implements StudentService {
/*根据studentName属性搜索Student 搜索的属性要和实体的属性保持一致 */
@SearchIndex(by = "studentName")
public List<Student> search(Student student){
/*方法内部什么都不需要写*/
return null;
}
/*根据schoolName属性搜索Student */
@SearchIndex(by = "schoolName")
public List<Student> search(Student Student){
/*方法内部什么都不需要写*/
/*如果再索引中未查到对应信息,可通过该方法设置默认查询,比如往数据库进行like模糊匹配*/
return searchWithLikeByName(schoolName);
}
}
注意:搜索结果仅仅是搜索出加上@IndexId和@IndexColumn的字段,具体内容自行往业务数据库查询
使工具类使用
public class IndexManager{
/*创建索引*/
public static void createIndex(IndexContent indexContent);
/*删除索引*/
public static void deleteIndex(String idName, String idValue,Class entityClass);
/*搜索 详见源码的demo项目*/
public static <T> List<T> searchIndexIds(String name, String value,Class<?> entityClass);
/*搜索 详见源码的demo项目*/
public static <T> List<T> searchIndexObjects(String name, String value,Class entityClass);
public static void deleteAll();
/*为对象创建索引*/
public static void createIndex(Object entity);
public static void createIndexs(List<Object> entities);
}
源码
有用的话可以Star支持一下,让作者增强信心,好好维护和升级
Gitee文章来源:https://www.toymoban.com/news/detail-430645.html
很简单的demo项目文章来源地址https://www.toymoban.com/news/detail-430645.html
到了这里,关于SimSearch:一个轻量级的springboot项目索引构建工具,实现快速模糊搜索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!