Как получить минимальную и максимальную цену из Hibernate Search - PullRequest
0 голосов
/ 06 января 2019

Я хочу добавить функцию фильтрации для продуктов, как у большинства сайтов электронной коммерции. Как получить минимальную и максимальную цену в зависимости от выбранной категории?

Я реализовал поиск по продукту с использованием поиска в спящем режиме с использованием данных весенней загрузки 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 голосов
/ 07 января 2019

В Hibernate Search нет функции, позволяющей получить минимальное и максимальное значения (что потребует агрегирования), но, к счастью, есть функция, которая должна точно соответствовать тому, что вам нужно: огранка .

Короче говоря, это позволяет перед запросом определить несколько диапазонов цен, например, [$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;

    ...

}

Тогда вам следует переиндексировать ваши данные .

Затем напишите ваш запрос так:

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 будет содержать каждый соответствующий фасет для вашего поиска.

...