如何从休眠搜索获取最低和最高价格

时间:2019-01-06 19:14:48

标签: java hibernate hibernate-search

我想为大多数电子商务网站提供的产品添加过滤器功能。如何根据所选类别获得最低和最高价格?

我已经使用休眠搜索和Spring Boot数据JPA实现了产品过滤器搜索...我正在使用布尔查询生成器根据用户实际从过滤器中选择的内容创建动态查询。让我们举个例子...假设我选择的是男士服装类别,并且我也获得了带有左侧过滤器的服装类别产品的结果。.假设在该类别中,我只允许选择价格范围滑块100到100,这意味着最低产品价格为100,最高价格为1000 ...之后我正在使用左侧过滤器(例如尺寸和品牌等)过滤产品数据。如果我选​​择了一个品牌,则再次使用新的价格值刷新数据,该价格值是仅具有品牌类别的服装产品的最小和最大值。搜索?

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);

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

Query categoryQuery = queryBuilder.keyword().onFields("subcategory.category.categoryName").matching("Clothing")
                .createQuery();

BooleanQuery.Builder builder = new BooleanQuery.Builder();

builder.add(categoryQuery, BooleanClause.Occur.MUST);

FullTextQuery query = fullTextEntityManager.createFullTextQuery(builder.build(), Product.class);
query.getResultList();

上面是示例代码,我在其中选择类别的所有产品。在这种情况下,我应该如何创建查询以从选定类别中获取最低和最高价格,并添加额外的过滤器,这将再次更改我的旧价格值。给我建议。我希望像大多数电子商务网站一样具有相同的功能来过滤产品,或者有另一种方法可以做到这一点。。。谢谢您。

1 个答案:

答案 0 :(得分:0)

Hibernate Search中没有允许您获取最小值和最大值的功能(这需要聚合),但是幸运的是,有一项功能应与您的需求完全匹配:faceting

简而言之,这允许您在查询之前定义多个价格范围,例如[$0, $10)[$10, $50)[$100, $200)[$200, $500)[$1000, infinite)。然后,当您获得查询结果时,还将为您提供每个范围的匹配文档数,使您可以向用户显示适当的过滤器(并隐藏不包含任何结果的范围)。

您将需要在您的实体中添加以下内容:

@Entity
@Indexed
public class Product {

    @Field(analyze = Analyze.NO) // You already have something like this, make sure to set analyze = NO
    @Facet(forField = "price", encoding = FacetEncodingType.DOUBLE) // You need to add this
    private double price;

    ...

}

然后您应该reindex your data

然后像这样编写查询:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);

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

Query categoryQuery = queryBuilder.keyword().onFields("subcategory.category.categoryName").matching("Clothing")
                .createQuery();

BooleanQuery.Builder builder = new BooleanQuery.Builder();

builder.add(categoryQuery, BooleanClause.Occur.MUST);

FullTextQuery query = fullTextEntityManager.createFullTextQuery(builder.build(), Product.class);

// Create the faceting request
FacetingRequest priceFacetingRequest = builder.facet()
    .name("priceFaceting")
    .onField("price")
    .range()
    .below(10).excludeLimit()
    .from(10).to(20).excludeLimit()
    .from(50).to(100).excludeLimit()
    .from(100).to(200).excludeLimit()
    .from(200).to(500).excludeLimit()
    .from(500).to(1000).excludeLimit()
    .above(1000)
    .createFacetingRequest();

// retrieve facet manager and apply faceting request
FacetManager facetManager = fullTextQuery.getFacetManager();
facetManager.enableFaceting(priceFacetingRequest);

// Retrieve the faceting results
List<Facet> facets = facetManager.getFacets("priceFaceting");

// Process the facets
// The list will contain one element per facet defined above,
// i.e. "(-infinity,10)", "[10,20)", "[50,100)", "[100,200)", "[200,500)", "[500,1000)","[1000,+infinity)"
// Note that by defaults, facets with 0 matching document will be omitted.
for (Facet facet : facets) {
    String rangeAsString = facet.getValue();
    int matchingDocumentCount = facet.getCount();
    // ... do something with the data ...
}

facets将包含您搜索的每个相关方面。