无需重复搜索 - 聚合和tophit

时间:2016-09-13 21:25:35

标签: elasticsearch

我开始使用ElasticSearch并且非常喜欢它,但是我很容易陷入非常简单的情况。 我正在索引这样的工人结构: NAME SURENAME ID AGE SEX NAME_SURENAME BIRTH_DATE

 NAME_SURENAME - not analyzed - this field is indexed for grouping purposes
 NAME, SURENAME - analyzed

任务很简单 - 搜索按birth_date排序的5个独特工人(唯一意味着相同的名称和确定名称,即使他们处于不同的年龄并且是不同的人)

我读到了有关聚合查询的内容,据我所知,我只能获得没有文档的聚合。不幸的是,我按名称和确定名进行汇总,所以我在桶中的结果中没有其他字段,例如至少是文档ID字段。但我也读到了关于TopHit聚合,它返回文档,我尝试了它 - 下面的第二个想法。

我有两个想法

1)不使用聚合,只搜索5个工作者,在java中过滤重复项,然后再搜索工作者并在Java中过滤重复项,直到达到5个唯一结果

2)使用聚合。我的事件尝试如下,它甚至适用于测试数据,但因为这是我的第一次,请建议,无论是意外工作还是正确完成?所以一般来说我认为我可以使用一个TopHit文档获得5个桶。我不知道如何选择TopHit文档,但似乎有效。以下是代码

String searchString = "test";

 BoolQueryBuilder query = boolQuery().minimumNumberShouldMatch(1).should(matchQuery("name", searchString).should(matchQuery("surename", searchString));

            TermsBuilder terms = AggregationBuilders.terms("namesAgg").size(5);

            terms.field("name_surename");

            terms.order(Terms.Order.aggregation("birthAgg", false)).subAggregation(AggregationBuilders.max("birthAgg")
                    .field("birth_date")
                    .subAggregation(AggregationBuilders.topHits("topHit").setSize(1).addSort("birth_date", SortOrder.DESC));


            SearchRequestBuilder searchRequestBuilder = client.prepareSearch("workers")
                     .addAggregation(terms).setQuery(query).setSize(1).addSort(SortBuilders.fieldSort("birth_date")
                            .order(SortOrder.DESC));

            Terms aggregations = searchRequestBuilder.execute().actionGet().getAggregations().get("namesAgg");

            List<Worker> results = new ArrayList<>();
            for (Terms.Bucket bucket : aggregations.getBuckets()) {
                Optional<Aggregation> first = bucket.getAggregations().asList().stream().filter(aggregation -> aggregation instanceof TopHits).findFirst();
                SearchHit searchHitFields = ((TopHits) first.get()).getHits().getHits()[0];

                Transformer<SearchHit, Worker> transformer = transformers.get(Worker.class);
                Worker transform = transformer.transform(searchHitFields);
                results.add(transform);
            }
            return results;//

0 个答案:

没有答案