什么是替代FullTextQuery.setCriteriaQuery()在Hibernate搜索6?



我正在将Hibernate Search 5迁移到Hibernate Search 6。虽然,文档确实很有帮助,但我无法在Hibernate Search 6中找到标准查询的替代方法,并且没有从文档中得到足够的信息。

这是我试图转换的Hibernate Search 5查询,

final Criteria criteria = entityManager.unwrap(Session.class).createCriteria(KnowledgeData.class);
criteria.add(Restrictions.eq("deleted", knowledgeSearchRequest.isDeleted()));
if (knowledgeSearchRequest.isPublished()) {
criteria.add(Restrictions.eq("published", knowledgeSearchRequest.isPublished()));
}
if (!allDesk) {
criteria.add(Restrictions.eq("deskId", deskId));
knowledgeSearchRequest.setDesk(deskId);
} else {
Disjunction orJunction = Restrictions.disjunction();
for (String desk : knowledgeSearchRequest.getDeskIds()) {
orJunction.add(Restrictions.eq("deskId", desk));
}
criteria.add(orJunction);
}
if (knowledgeSearchRequest.getLang() != null && knowledgeSearchRequest.getLang().size() > 0) {
criteria.createAlias("language", "lan");
Disjunction disJunction = Restrictions.disjunction();
for (String lang : knowledgeSearchRequest.getLang()) {
disJunction.add(Restrictions.eq("lan.elements", lang));
}
criteria.add(disJunction);
}
if (knowledgeSearchRequest.getTags() != null && knowledgeSearchRequest.getTags().size() > 0) {
criteria.createAlias("tags", "tag");
Disjunction disJunction = Restrictions.disjunction();
for (String tag : knowledgeSearchRequest.getTags()) {
disJunction.add(Restrictions.eq("tag.elements", tag));
}
criteria.add(disJunction);
}
criteria.add(Restrictions.ne("dataType", DataType.FOLDER));
// if (userProvider.getCurrentUser().isSystemUser() || visibleToUser) {
final List<DataVisibility> visibility = new ArrayList<>();
visibility.add(DataVisibility.PUBLIC);
if (knowledgeSearchRequest.isAddCpUserDocs()) {
visibility.add(DataVisibility.ALL_USERS_OF_CUSTOMER_PORTAL_ONLY);
}
if (knowledgeSearchRequest.isIncludeCpDocs()) {
visibility.add(DataVisibility.CUSTOMER_PORTAL);
visibility.add(DataVisibility.ALL_SIGNED_IN_USERS_OF_CUSTOMER_PORTAL_ONLY);
visibility.add(DataVisibility.ALL_USERS_OF_CUSTOMER_PORTAL_ONLY);
}
criteria.add(Restrictions.in("visibility", visibility));
// }
if (knowledgeSearchRequest.isPublished()) {
final long now = System.currentTimeMillis();
criteria.add(Restrictions.or(
Restrictions.and(Restrictions.isNotNull("validFrom"), Restrictions.lt("validFrom", now)),
Restrictions.isNull("validFrom")));
criteria.add(Restrictions.or(
Restrictions.and(Restrictions.isNotNull("validTo"), Restrictions.gt("validTo", now)),
Restrictions.isNull("validTo")));
}

并且,到目前为止我建立的谓词是

searchPredicateFactory.bool(
f -> f.should(searchPredicateFactory.phrase().field(KnowledgeData.STANDARD_FIELD_NAME_NAME).boost(3)
.field(KnowledgeData.STANDARD_FIELD_NAME_DISPLAY_NAME).boost(3)
.field("description").boost(2).field("content").matching(resultantQuery))
.should(searchPredicateFactory.wildcard().field(KnowledgeData.STANDARD_FIELD_NAME_NAME).boost(3)
.field(KnowledgeData.STANDARD_FIELD_NAME_DISPLAY_NAME).boost(3)
.field("description").boost(2).field("content").matching(resultantQuery))).toPredicate();

任何线索都是感激的。

这是我试图转换的Hibernate搜索5查询,

我要挑剔一下:这不是Hibernate Search 5查询,这是Hibernate (ORM)标准查询。这些限制是对数据库执行的,而不是对搜索索引执行的。

根据问题的标题,我假设您正在使用FullTextQuery.setCriteriaQuery()将这些限制添加到Hibernate Search查询中。请注意,Hibernate Search 5中的文档声明"应该避免在您的Criteria查询中使用限制(即where子句)"。javadoc甚至更进一步,声明"没有where限制可以被定义"。

不管……至少在某些情况下,它在Hibernate Search 5中是可以工作的。

现在,要将此迁移到Hibernate Search 6+,有一个详细的迁移指南,其中有一节专门针对您的问题:

Hibernate Search 6不允许在搜索查询中添加Criteria对象。

[…]

如果您的目标是应用由SQL "where"在数据库中执行子句,将查询重新设计为实体ID上的项目,并在搜索查询之后执行JPA/Hibernate ORM查询以过滤实体并加载它们。

简而言之,像这样做:

List<Long> ids = Search.session(entityManager).search(MyEntity.class)
.select(f -> f.id(Long.class))
.where(f -> ...)
.fetchHits(20);
criteria.add(Restrictions.in("id", ids));
List<MyEntity> hits = criteria.list();

注意这只是一个快速修复:就像Hibernate Search 5中的setCriteria一样,这可能会执行得非常糟糕,在分页方面表现非常糟糕,并且可能导致错误的命中计数。

我建议索引您在Criteria查询中使用的属性,并仅使用Hibernate Search定义整个查询,以避免对Elasticsearch运行一次查询,然后再对数据库运行一次查询。

参见https://hibernate.atlassian.net/browse/HSEARCH-3630

相关内容

  • 没有找到相关文章

最新更新