Commit f2814497 authored by Jean-Baptiste Nizet's avatar Jean-Baptiste Nizet
Browse files

feat: recompute aggregations in each search by taking into account the other aggregations

parent e085522f
......@@ -22,6 +22,7 @@ import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
......@@ -33,6 +34,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.EntityMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
......@@ -117,19 +119,54 @@ public class GeneticResourceDaoImpl implements GeneticResourceDaoCustom {
.withFilter(refinementQuery)
.withPageable(page);
if (aggregate) {
Stream.of(RareAggregation.values()).forEach(rareAggregation ->
builder.addAggregation(AggregationBuilders.terms(rareAggregation.getName())
.field(rareAggregation.getField())
.missing(GeneticResource.NULL_VALUE)
.size(rareAggregation.getType().getMaxBuckets())));
}
if (highlight) {
builder.withHighlightFields(new HighlightBuilder.Field("description").numOfFragments(0));
}
return elasticsearchTemplate.queryForPage(builder.build(), GeneticResource.class, geneticResourceHighlightMapper);
AggregatedPage<GeneticResource> resultWithoutAggregations =
elasticsearchTemplate.queryForPage(builder.build(), GeneticResource.class, geneticResourceHighlightMapper);
if (!aggregate) {
return resultWithoutAggregations;
}
List<Terms> termsList =
Stream.of(RareAggregation.values())
.map(rareAggregation -> agg(query, refinements, rareAggregation))
.collect(Collectors.toList());
return new AggregatedPageImpl<>(resultWithoutAggregations.getContent(),
resultWithoutAggregations.getPageable(),
resultWithoutAggregations.getTotalElements(),
new Aggregations(termsList),
resultWithoutAggregations.getScrollId(),
resultWithoutAggregations.getMaxScore());
}
private Terms agg(String query, SearchRefinements refinements, RareAggregation rareAggregation) {
MultiMatchQueryBuilder fullTextQuery = multiMatchQuery(query, SEARCHABLE_FIELDS.toArray(new String[0]));
BoolQueryBuilder refinementQuery = boolQuery();
for (RareAggregation term : refinements.getTerms()) {
if (term != rareAggregation) {
refinementQuery.must(createRefinementQuery(refinements, term));
}
}
BoolQueryBuilder completeQuery = boolQuery().must(fullTextQuery).must(refinementQuery);
TermsAggregationBuilder aggregation =
AggregationBuilders.terms(rareAggregation.getName())
.field(rareAggregation.getField())
.missing(GeneticResource.NULL_VALUE)
.size(rareAggregation.getType().getMaxBuckets());
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder()
.withQuery(completeQuery)
.addAggregation(aggregation)
.withPageable(NoPage.INSTANCE);
AggregatedPage<GeneticResource> geneticResources = elasticsearchTemplate.queryForPage(builder.build(),
GeneticResource.class);
return geneticResources.getAggregations().get(rareAggregation.getName());
}
/**
......
......@@ -74,7 +74,7 @@ export class SearchComponent implements OnInit {
// we consider all parameters as potential aggregations, except `query` and `page`
this.aggregationCriteria = this.extractCriteriaFromParameters(params);
// launch the search
return this.searchService.search(this.query, aggregate, this.aggregationCriteria, page)
return this.searchService.search(this.query, true, this.aggregationCriteria, page)
// handle a potential error, by returning no result
// but allow to trigger a new search
.pipe(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment