[英]Performing faceted search with elastic search repositories using spring data?
I am in the need of performing faceted search using elastic search repositories developed using spring data. 我需要使用使用spring数据开发的弹性搜索存储库执行多面搜索。
One of the repositories which I have created are 我创建的存储库之一是
public interface EmployeeSearchRepository extends ElasticsearchRepository<Employee, Long> { }
it does provide a method called search with a signature: 它确实提供了一种带有签名的名为search的方法:
FacetedPage<Employee> search(QueryBuilder query, Pageable pageable);
but the getFacets method of the FacetedPage returns null. 但是FacetedPage的getFacets方法返回null。 How can I query to generate the facets?
如何查询以生成构面?
I have the same problem and it seems that it is not implemented (yet). 我有同样的问题,似乎还没有实现。 If you look at DefaultResultMapper.mapResults() it calls response.getFacets() which is always null.
如果查看DefaultResultMapper.mapResults(),它将调用response.getFacets(),该值始终为null。
Note that facets are deprecated in elasticsearch and you should use aggregations instead. 请注意,在Elasticsearch中不建议使用构面,而应使用聚合。 So maybe the contributors of the project are refactoring it?
那么也许项目的贡献者正在重构它?
I worked this around by writing my own results mapper class which extends the DefaultResultMapper but also converts the aggregations to FacetResults. 我通过编写自己的结果映射器类来解决此问题,该类扩展了DefaultResultMapper,但也将聚合转换为FacetResults。
SomethingResultsMapper: SomethingResultsMapper:
@Override
public <T> FacetedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
FacetedPage<T> facetedPage = super.mapResults(response, clazz, pageable);
//Process Aggregations.
if (response.getAggregations() != null) {
for (Aggregation aggregations : response.getAggregations().asList()) {
final Filter filterAggregations = (Filter) aggregations;
for (Aggregation filterAgg : filterAggregations.getAggregations().asList()) {
if (filterAgg instanceof Terms) {
final Terms aggTerm = (Terms) filterAgg;
if (!aggTerm.getBuckets().isEmpty()) {
facetedPage.getFacets().add(processTermAggregation(aggTerm));
}
} else if (filterAgg instanceof Nested) {
final Nested nestedAgg = (Nested) filterAgg;
for (Aggregation aggregation : nestedAgg.getAggregations().asList()) {
final Terms aggTerm = (Terms) aggregation;
if (!aggTerm.getBuckets().isEmpty()) {
facetedPage.getFacets().add(processTermAggregation(aggTerm));
}
}
} else {
throw new IllegalArgumentException("Aggregation type not (yet) supported: " + filterAgg.getClass().getName());
}
}
}
}
return facetedPage;
}
private FacetResult processTermAggregation(final Terms aggTerm) {
long total = 0;
List<Term> terms = new ArrayList<>();
List<Terms.Bucket> buckets = aggTerm.getBuckets();
for (Terms.Bucket bucket : buckets) {
terms.add(new Term(bucket.getKey(), (int) bucket.getDocCount()));
total += bucket.getDocCount();
}
return new FacetTermResult(aggTerm.getName(), FacetConfig.fromAggregationTerm(aggTerm.getName()).getLabel(),
terms, total, aggTerm.getSumOfOtherDocCounts(), aggTerm.getDocCountError());
}
Then i created a custom Spring data repository (see the docs) and defined a custom method where i provide my SomethingResultsMapper: 然后,我创建了一个自定义的Spring数据存储库(请参阅文档),并定义了一个自定义方法,其中提供了SomethingResultsMapper:
@Override
public FacetedPage<Something> searchSomething(final SearchQuery searchQuery) {
return elasticsearchTemplate.queryForPage(searchQuery, Something.class, new SomethingResultsMapper());
}
EDIT: I think this one is being fixed by https://jira.spring.io/browse/DATAES-211 编辑:我认为这是由https://jira.spring.io/browse/DATAES-211修复的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.