休眠搜索,在其他过滤器上方进行过滤

时间:2018-07-30 07:34:05

标签: java lucene hibernate-search

是否可以在{em>休眠搜索中使用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()
            );
}

我一直在搜索问题和休眠文档,但是所有示例都带有固定值字段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());
}

1 个答案:

答案 0 :(得分:1)

您要执行的是一个关系查询。 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 Search进行查询,而只能通过HQL/JPQL或{{3 }}。