If I have some Products with color and size. Jeans Blue Size L Jeans Red Size S T-shirt REd Size S and so on..
Doing a facet search using hibernate-search works as quite well. But if I select one of the criteria, I would expect that the values of the own group are not filtered. for Example
Color Red (2) Blue (3)
Size S (1) M (2) L (3)
If I selected the red color using something like this
fullTextQuery.getFacetManager().getFacetGroup(FACET_COLOR).selectFacets(colorFacet)
This selection should influence the overall Results of the Item List and the Result of the Size Facets. But of course I don't want that the Blue option to vanish. My expected behavior is pretty much how its done on bigger ecommerce sites. But in my example the selected color red also changes the own group.
I'm I missing something? This is my example:
public SearchResponse search(SearchRequest request)
{
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
QueryBuilder queryBuilder =
fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Product.class).get();
BooleanJunction bool = queryBuilder.bool().must(queryBuilder.all().createQuery());
FacetingRequest colorFacetRequest = queryBuilder.facet().name(FACET_COLOR).onField(FACET_COLOR)
.discrete().createFacetingRequest();
FacetingRequest sizeFacetRequest = queryBuilder.facet().name(FACET_SIZE).onField(FACET_SIZE)
.discrete().createFacetingRequest();
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(bool.createQuery(), Product.class);
fullTextQuery.getFacetManager().enableFaceting(colorFacetRequest);
fullTextQuery.getFacetManager().enableFaceting(sizeFacetRequest);
if (!StringUtils.isEmpty(request.color))
{
fullTextQuery.getFacetManager().getFacets(FACET_COLOR)
.stream().filter(f -> f.getValue().equals(request.color)).forEach(found -> {
fullTextQuery.getFacetManager().getFacetGroup(FACET_COLOR).selectFacets(found);
});
}
if (!StringUtils.isEmpty(request.size))
{
fullTextQuery.getFacetManager().getFacets(FACET_SIZE)
.stream().filter(f -> f.getValue().equals(request.size)).forEach(found -> {
fullTextQuery.getFacetManager().getFacetGroup(FACET_SIZE).selectFacets(found);
});
}
List<SearchFacet> colorFacet = fullTextQuery.getFacetManager().getFacets(FACET_COLOR)
.stream().map(f -> new SearchFacet(f.getValue(), f.getCount())).collect(Collectors.toList());
List<SearchFacet> sizeFacet = fullTextQuery.getFacetManager().getFacets(FACET_SIZE)
.stream().map(f -> new SearchFacet(f.getValue(), f.getCount())).collect(Collectors.toList());
return new SearchResponse(sizeFacet, colorFacet, fullTextQuery.getResultList());
}
disabling each group before the getFacets Methods does not seem very clean
Thanks
Let me start my answer by explaining a key difference to help you with your search.
The first difference is that
filters
needs to be a string andfacetFilters
needs to be anarray
You can use the second, ie
facetFilters
array to pass jobs in Paris, London etc .that will collectively trim down your data set
You have to pick one at the top level and then the other would be a nested criteria inside.
For eg you can either do a top level filter or top level facet search and then apply the filters within.
You could achieve this in different ways, for eg he gets the records and then drills down. from @Gunnar answer
Record lastRecord = ...;
QueryBuilder queryBuilder = fullTextSession
.getSearchFactory()
.buildQueryBuilder()
.forEntity(Record.class).get();
Query query = queryBuilder.range()
.onField( "created" )
.above( lastRecord.getCreated() )
.createQuery();
FullTextQuery fullTextQuery = fulllTextSession.createFullTextQuery(
query, Record.class
);
Now if you want to aggreate those query results only
SearchSession searchSession = Search.session( entityManager );
AggregationKey<Map<Genre, Long>> countsByGenreKey = AggregationKey.of( "countsByGenre" );
SearchResult<Book> result = searchSession.search( Book.class )
.where( f -> f.match().field( "title" )
.matching( "robot" ) )
.aggregation( countsByGenreKey, f -> f.terms()
.field( "genre", Genre.class ) )
.fetch( 20 );
Map<Genre, Long> countsByGenre = result.aggregation( countsByGenreKey );
The last scenario from your jobs comments is by doing a collection of filters like here
There is already an enhancement request about this: https://hibernate.atlassian.net/browse/HSEARCH-713
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.