借鉴:https://blog.csdn.net/wslyk606/article/details/84315862?spm=1001.2014.3001.5506

1 引言

项目中es库中存储了大量的文档信息,而且是分段存储
需求:根据文档内容检索出当前的文档。
问题:检索出了大量的相同文档,如何去重呢?
大量相同文档伴生的问题:
es检索到10000条以上数据就会抛错
java Api中只能显示10条检索出来的数据

2 Elasticsearch去重功能

2.1 关系型数据库如何去重

关系型数据库中,比如MySQL,可以通过distinct进行去重,一般分为两种:
1 ) 统计去重后的数量
select distinct(count(1)) from test;
2 ) 获取去重后的结果
select distinct name,sex from person;
test,person为对应的表名。

2.2 es如何去重

1 ) es查询结果进行去重计数

es的去重计数工卡可以通过es的聚合功能+Cardinality聚合函数来实现

2 ) es查询结果去重后显示

去重显示有两种方式:

(1) 使用字段聚合+top_hits聚合方式

(2)使用collapse折叠功能(5.3后版本提供)

我这里使用的es是2.4的版本,JavaApi使用的是第一种方式,5.x,6.x的版本也可以使用

2.3 es折叠去重

这里介绍es的折叠去重,原因是简单,性能好。
注意:collapse的字段需要为keyword或者number类型。

POST your_index/_search
{
    "query":{
        "match_all":{

        }
    },
    "collapse":{
    	# 根据哪个字段去去重 uid
        "field":"uid"
    }
}

java代码 es6.5.4版本

			RestHighLevelClient client = esClient.getElasticsearchClient();

            SearchRequest request = new SearchRequest(index);
            request.types(type);

            // 构建查询器
            SearchSourceBuilder builder = new SearchSourceBuilder();
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            // 需要去重的字段
            CollapseBuilder collapseBuilder = new CollapseBuilder("fileId");
            // 复合查询
            if (ObjectUtil.isNotNull(esQueryParamPaginationBo.getUserId())) {
                boolQuery.must(QueryBuilders.matchQuery("userId", esQueryParamPaginationBo.getUserId()));
            }
            if (StrUtil.isNotBlank(esQueryParamPaginationBo.getFileName())) {
                boolQuery.must(QueryBuilders.matchQuery("fileName", esQueryParamPaginationBo.getFileName()));
            }
            if (StrUtil.isNotBlank(esQueryParamPaginationBo.getContent())) {
                boolQuery.must(QueryBuilders.matchQuery("content", esQueryParamPaginationBo.getContent()));
            }
            if (StrUtil.isNotBlank(esQueryParamPaginationBo.getTransContent())) {
                boolQuery.must(QueryBuilders.matchQuery("transContent", esQueryParamPaginationBo.getTransContent()));
            }

            // 组装查询条件
            builder.query(boolQuery).size(querySize);
            builder.collapse(collapseBuilder);
            // 组装请求
            request.source(builder);

            // 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐