具有标准投影查询的休眠搜索

hibernate-search with criteria projection queries

我正在使用 hibernate search 进行所有自由文本/facet 搜索。我正在尝试提高性能,但我注意到我的查询有很多不需要的选择和连接。我的目标是创建一个投影查询,现在我知道我可以通过将项目存储在索引中来直接使用 hibernate-search 来执行此操作,但我想尝试避免这样做会消耗内存。我的想法是 return 来自 hibernate-search 的 pks 列表,然后将它们传递到我的条件查询中。我的问题是,这是正确的方法吗?

在回答你的问题之前,让我试着澄清一些事情,尽管我认为你已经理解了它们。

Hibernate Search 是使用 Apache Lucene 的 Hibernate ORM 的扩展。根据其配置,它将在 Lucene 索引中索引您的托管实体的一部分。然后您可以构建一个所谓的 "free-text search" 查询,它搜索 Lucene 索引。这独立于任何以存储实体的关系数据库为目标的 JPA 或 Hibernate ORM 特定查询功能。

返回 "free-text" 搜索。 Hibernate Search 的默认行为确实是 运行 针对 Lucene 索引的指定 Lucene 查询以检索实体 ID 列表。这些 id 然后用于使用 Hibernate ORM 功能从数据库进行批量加载。

现在回答你的问题。

I'm trying to increase performance and I'm noticing my query has a lot of unneeded selects and joins.

这里确实要区分一下。有两个查询发生。针对自由文本索引的 Lucene 查询和 Hibernate ORM 查询从数据库中引导匹配的实体。既然你说的是 select 和 join,我想你说的是后者。如果 SQL 查询是性能瓶颈并且连接过多等,性能调优应该考虑域模型的复杂性及其与 Hibernate ORM(惰性关联等)相关的调优。

My goal is to create a projection query, now I know I can do this directly with hibernate-search by storing items in the index

是的,如果您不需要托管实体并且只对部分数据感兴趣,投影查询是可行的方法。同样,有两种类型。 Hibernate Search 投影查询和 Hibernate ORM 投影查询。前者,正如您已经提到的,在 Lucene 索引中存储额外的数据并针对这些数据执行投影。在这种情况下,好处是根本没有数据库访问权限。后一种投影类型,是针对关系数据库的投影。将只加载 selected 属性(通过 SQL),而不是加载完整实体。

My thought was to return a list of pks from hibernate-search and then pass them into my criteria query.

有人可以这样做,但我认为这不是最好的方法。为此,您需要投影查询。首先是 Hibernate Search 投影查询以获取实体 ID 列表,然后是 ORM 投影查询以从数据库加载属性。如果将相关属性存储在 Lucene 索引中,则可以完全跳过第二个投影。

因此,如果性能是您的最终目标,那就是正确的选择。不过,您似乎担心内存消耗。 IMO Lucene 和 Hibernate Search 在尝试尽可能高效方面做得很好。我不会出于过早的优化考虑而放弃纯 Hibernate 搜索投影方法。