休眠搜索,在其他过滤器之上过滤

Hibernate search, filter above other filter

是否可以在 hibernate search 中使用 above 使用其他字段编写范围查询?如果我尝试使用字符串会引发错误:

private BooleanJunction addInCriticalStock(QueryBuilder queryBuilder, BooleanJunction booleanJunction, boolean inCriticalStock) {
    return booleanJunction
            .must(queryBuilder
                    .range()
                    .onField("currentStock")
                    .above("minimumStock") // This is other field, also "@minimumStock"
                    .createQuery()
            );
}

我一直在搜索问题和 hibernate 文档,但所有示例都带有固定值字段,si,这可能吗?

编辑

我使用的标准 api 据我所知:

private FullTextQuery searchQuery(SearchRequest searchRequest, String... projection) {
    FullTextEntityManager fullTextEntityManager =
            org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);

    final QueryBuilder queryBuilder = fullTextEntityManager
            .getSearchFactory()
            .buildQueryBuilder()
            .forEntity(Product.class)
            .get();

    final BooleanJunction baseQuery = queryBuilder
            .bool();

    BooleanJunction query = addOptionalSearchTerm(queryBuilder, baseQuery, searchRequest.getSearchTerm());
    query = addOptionalProductType(queryBuilder, query, searchRequest.getProductType());
    query = addOptionalSupplier(queryBuilder, query, searchRequest.getSupplier());
    query = addOptionalYear(queryBuilder, query, searchRequest.getYear());
    query = addOptionalVersion(queryBuilder, query, searchRequest.getVersion());
    query = addOptionalModel(queryBuilder, query, searchRequest.getModel());
    query = addOptionalBrand(queryBuilder, query, searchRequest.getBrand());
    query = addOptionalInExistence(queryBuilder, query, searchRequest.getInExistence());
    query = addOptionalInCriticalStock(queryBuilder, query, searchRequest.getInCriticalStock());

    Query combinedQuery = query.createQuery();

    Sort sort = queryBuilder.sort()
            .byScore()
            .andByField("description")
            .createSort();

    return fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class)
            .setSort(sort)
            .setProjection(projection)
            .setFirstResult((searchRequest.getPage() - 1) * searchRequest.getTop())
            .setMaxResults(searchRequest.getTop());
}

您要执行的是关系查询。 Hibernate Search 不支持这样的查询。可以通过依赖 Lucene 中较低级别的 API 来实现它们,但老实说,我不建议这样做,除非,也许,对于 Lucene 专家:它不容易使用,应该仔细分析性能影响。

一般来说,解决这类问题的方法是索引一个额外的字段,例如 "minimumStockDifference",并检查它是否大于零:

@Indexed
@Entity
public class Product {

  private int minimumStock;
  private int currentStock;


  @Transient
  @Field
  public int getMinmumStockDifference() {
    return currentStock - minimumStock;
  }

}

那么您的查询变为:

private BooleanJunction addInCriticalStock(QueryBuilder queryBuilder, BooleanJunction booleanJunction, boolean inCriticalStock) {
    return booleanJunction
            .must(queryBuilder
                    .range()
                    .onField("minimumStockDifference")
                    .above(0)
                    .createQuery()
            );
}

小心,如果您必须从另一个实体获取 minimumStock,请适当放置 @ContainedIn annotations,以便您的 Product 实体在 minimumStock 时重新编制索引变化。

请注意,如果您不需要在同一个查询中进行全文搜索,您可以简单地不对该查询使用 Hibernate 搜索,而是通过 HQL/JPQL or the criteria API.[= 依赖 Hibernate ORM 查询。 18=]