在休眠 FullTextEntityManager 查询中使用子查询

Using a subquery in a hibernate FullTextEntityManager query

我正在尝试使用休眠 FullTextEntityManager 查询修改一些代码。基本上它目前有效,但我想将结果限制为 table(给定类型的最新记录)中的记录子集。

因此,例如要搜索的数据的基础查询可能是沿着这些方向的(仅用于演示,我还没有解析这个!)

SELECT name, address 
FROM Persons p
WHERE p.name = sq.name
FROM 
(SELECT name, max(datemodified)
 FROM Persons 
  GROUP BY name) sq

目前 java 代码只是从原始 table 中选择(基本上这就是我认为的 forEntity 选项)

FullTextEntityManager ftem = Search.getFullTextEntityManager(getEntityManager());

SearchFactory sf= ftem.getSearchFactory();
QueryContextBuilder qcb = sf.buildQueryBuilder();
QueryBuilder qb= qcb.forEntity(entityClass).get();

//processSearchExpression builds a lucene style full text search
org.apache.lucene.search.Query q= processSearchExpression();

FullTextQuery ftq= ftem.createFullTextQuery(q, entityClass);

所以基本上我认为我已经非常忠实地把要点放在那里了。我不太清楚的是如何添加子查询或产生类似功能的东西,以便我可以只查询每种类型的最新记录?

目前,将 ORM 查询与搜索查询相结合的最简单解决方案是向您的搜索查询添加一个子句以按 ID 进行过滤。

FullTextEntityManager ftem = Search.getFullTextEntityManager(getEntityManager());

SearchFactory sf= ftem.getSearchFactory();
QueryBuilder qb= sf.buildQueryBuilder().forEntity(entityClass).get();

BooleanJunction<?> idJunction = qb.bool();
for (Long id : listIdsYouWant()) {
   idJunction.must(qb.match().onField("id").matching(id).createQuery());
}

org.apache.lucene.search.Query q = qb.bool()
   //processSearchExpression builds a lucene style full text search
    .must(processSearchExpression())
    .filteredBy(idJunction.createQuery)
    .createQuery();

FullTextQuery ftq= ftem.createFullTextQuery(q, entityClass);

如果这不是一个选项,您应该寻找一种方法来索引您需要使用 full-text 查询重现 SQL 查询的数据。

在您的情况下,您似乎正在使用 custom-built 版本控制系统。

一个解决方案是改用 Hibernate Envers,我上次检查它与 Hibernate Search 完全兼容。参见 http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#envers

另一种解决方案是将相同的文档 ID 分配给您认为相同的所有人。这样,索引中将永远只有一个人:最后一个被修改的人。参见 https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#id-annotation 但是,您可能 运行 在获取与给定文档匹配的实体时遇到一些麻烦,因为多个实体会匹配。这就是为什么使用 Envers 会更好。