我有一个实体,比如
class Employee {
private long id;
private String name;
private String title;
private String jobDescription; // Free Text
}
当调用以下url时,我可以搜索/过滤多个字段的数据
http://localhost:8080/employee?name=Jack&jobDescritpion=developer
无需任何代码即可使用以下存储库
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long>, QuerydslPredicateExecutor<Employee>, QuerydslBinderCustomizer<Employee>
QuerydslBinderCustomizer
将使用以下命令为所有String
字段生成like
查询:
@Override
default void customize(QuerydslBindings bindings, QEmployee employee) {
bindings.bind(String.class)
.first((StringPath path, String value) -> path.containsIgnoreCase(value));
}
这样我就可以为jobDescription
获得基本的文本搜索功能
当数据集变得很大时,比如100万,like
会降低性能。解决方案是将描述字段(甚至所有字段)索引到Lucene,并使用Hibernate Search
,以便对jobDescrription
我可以这样做:
SearchResult<Employee> searchResult = searchSession.search(Employee.class)
.where(f ->f.match()
.field("jobDescription")
.matching(keywords)
.fuzzy()).fetch(offset,size);
这里我有两个选择:
- Lucene索引
all fields
- 索引
only jobDescritpion
这两个选项我都可以。问题是我如何将其与JPA集成,以便以下url仍然有效,只是这次查询是从Hibernate Search索引构建并由JPA执行:
http://localhost:8080/employee?name=Jack&jobDescritpion=developer
如何通过JPASpecification
或QueryByDsl
或任何其他方式实现Hibernate Search
和JPA
之间的集成?
你真的只有一个选择,那就是索引Lucene中的所有字段。虽然依靠数据库WHERE
和Lucene查询来实现搜索查询是可能的,但它确实表现不佳,特别是在使用分页时。
关于如何通过JPASpecification
或QueryByDsl
使用Hibernate搜索查询…我对这项技术不太熟悉,所以对此持保留态度。
但是我知道有人试图将Hibernate Search 5(旧版本)集成到Snowdrop项目的Spring中。我假设您必须为Hibernate Search 6做同样的操作。
至于QueryDSL,据我所知,它仍然依赖于旧的Hibernate Search 5,所以它不能与Hibernate Search 6一起使用,直到需要它的人决定升级它。