当前位置: 首页 > 知识库问答 >
问题:

Spring数据聚合查询elasticsearch

洪俊能
2023-03-14

我尝试使用下面的elasticsearch查询来处理Spring数据。目的是为字段"serviceName"返回唯一的结果。就像SELECT DISTINCT serviceName from table与SQL数据库进行比较一样。

{
  "aggregations": {
    "serviceNames": {
      "terms": {
        "field": "serviceName"
      }
    }
  },
  "size":0
}

我将该字段配置为关键字,它使查询在index_name/_searchapi中完美运行,如下所示:

"aggregations": {
        "serviceNames": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "service1",
                    "doc_count": 20
                },
                {
                    "key": "service2",
                    "doc_count": 8
                },
                {
                    "key": "service3",
                    "doc_count": 8
                }
            ]
        }
    }

我的问题是,当我尝试使用StringQuery运行时,相同的查询在Spring数据中不起作用,我得到以下错误。我猜它使用不同的api来运行查询。

Cannot execute jest action , response code : 400 , error : {"root_cause":[{"type":"parsing_exception","reason":"no [query] registered for [aggregations]","line":2,"col":19}],"type":"parsing_exception","reason":"no [query] registered for [aggregations]","line":2,"col":19} , message : null

我尝试过使用SearchQuery类型来实现相同的结果,没有重复和没有对象加载,但我没有运气。下面的sinnipet展示了我是如何尝试这样做的。

java prettyprint-override">final TermsAggregationBuilder aggregation = AggregationBuilders
                .terms("serviceName")
                .field("serviceName")
                .size(1);
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices("index_name")
                  .withQuery(matchAllQuery())
                  .addAggregation(aggregation)
                  .withSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                  .withSourceFilter(new FetchSourceFilter(new String[] {"serviceName"}, new String[] {""}))
                  .withPageable(PageRequest.of(0, 10000))
                  .build();

有人知道如何在spring数据上实现无对象加载和对象属性不同的聚合吗?

我尝试了很多方法都没有成功打印对Spring数据的查询,但我不能,可能是因为我使用的是com.github.vanroy.springdata.jest.JestElasticsearch chTemboard实现。我得到了以下查询部分:

logger.info("query:" + searchQuery.getQuery());
logger.info("agregations:" + searchQuery.getAggregations());
logger.info("filter:" + searchQuery.getFilter());
logger.info("search type:" + searchQuery.getSearchType());

它打印:

query:{"match_all":{"boost":1.0}}
agregations:[{"serviceName":{"terms":{"field":"serviceName","size":1,"min_doc_count":1,"shard_min_doc_count":0,"show_term_doc_count_error":false,"order":[{"_count":"desc"},{"_key":"asc"}]}}}]
filter:null
search type:DFS_QUERY_THEN_FETCH

共有1个答案

益明朗
2023-03-14

我想,也许可以帮助别人。聚合不随查询结果一起提供,而是以其自身的结果提供,并且没有映射到任何对象。所得到的对象结果显然是elasticsearch为运行聚合所做的查询示例(可能不确定)。最后,我创建了一个方法,可以模拟SQL上的内容,从表中选择不同的\u列,但我认为这只适用于关键字字段,如果我没有错的话,它们的限制是256个字符。我在评论中解释了一些行。感谢@Val,因为我只有在调试成Jest代码并检查生成的请求和原始响应时才能弄清楚它。

public List<String> getDistinctField(String fieldName) {
    List<String> result = new ArrayList<>();

    try {
        final String distinctAggregationName = "distinct_field"; //name the aggregation

        final TermsAggregationBuilder aggregation = AggregationBuilders
                .terms(distinctAggregationName)
                .field(fieldName)
                .size(10000);//limits the number of aggregation list, mine can be huge, adjust yours

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withIndices("your_index")//maybe can be omitted
                .addAggregation(aggregation)
                .withSourceFilter(new FetchSourceFilter(new String[] { fieldName }, new String[] { "" }))//filter it to retrieve only the field we ar interested, probably we can take this out.
                .withPageable(PageRequest.of(0, 1))//can't be zero, and I don't want to load 10 results every time it runs, will always return one object since I found no "size":0 in query builder
                .build();
//had to use the JestResultsExtractor because com.github.vanroy.springdata.jest.JestElasticsearchTemplate don't have an implementation for ResultsExtractor, if you use Spring defaults, you can probably use it.
    final JestResultsExtractor<SearchResult> extractor = new JestResultsExtractor<SearchResult>() {
                @Override
                public SearchResult extract(SearchResult searchResult) {
                    return searchResult;
                }
            };

            final SearchResult searchResult = ((JestElasticsearchTemplate) elasticsearchOperations).query(searchQuery,
                    extractor);
            final MetricAggregation aggregations = searchResult.getAggregations();
            final TermsAggregation termsAggregation = aggregations.getTermsAggregation(distinctAggregationName);//this is where your aggregation results are, in "buckets".
            result = termsAggregation.getBuckets().parallelStream().map(TermsAggregation.Entry::getKey)
                    .collect(Collectors.toList());

        } catch (Exception e) {
            // threat your error here.
            e.printStackTrace();
        }
        return result;

    }
 类似资料:
  • 有人能帮我把这个mongoDB聚合转换成Spring数据mongo吗? 我试图在每个邀请函文件中获得未提醒与会者的电子邮件列表。 让它在mongo shell中运行,但需要在Spring data mongo中运行。 我的shell查询 ) 正如你们所看到的,这是我提出的,它在管道的项目和团队运作中并没有像预期的那样发挥作用。下面给出了生成的查询。 聚合对象创建 它创建以下查询 聚合对象生成的查询

  • >[danger] 注意!!! 使用聚合功能时,必须给它一个别名,以便能够从模型中访问它 > 聚合函数的计算,都是排除了 null 值,所以COUNT( id ) 一般推荐用非空的主键来计算 COUNT 计算数量 const { Sequelize } = app; // 查询班级总人数,按照姓名聚合 const ret = await Student.findAll({ attribut

  • 在应用中我们经常会用到一些统计数据,例如当前所有(或者满足某些条件)的用户数、所有用户的最大积分、用户的平均成绩等等,ThinkPHP为这些统计操作提供了一系列的内置方法,包括: 方法 说明 count 统计数量,参数是要统计的字段名(可选) max 获取最大值,参数是要统计的字段名(必须) min 获取最小值,参数是要统计的字段名(必须) avg 获取平均值,参数是要统计的字段名(必须) sum

  • 主要内容:aggregate() 方法,管道MongoDB 中的聚合操作用来处理数据并返回计算结果,聚合操作可以将多个文档中的值组合在一起,并可对数据执行各种操作,以返回单个结果,有点类似于 SQL 语句中的 count(*)、group by 等。 aggregate() 方法 您可以使用 MongoDB 中的 aggregate() 方法来执行聚合操作,其语法格式如下: db.collection_name.aggregate(aggr

  • 我使用Spring(引导)2.2.7与mongoDB 4.0运行在Debian Stretch(9.12)。我已经设置了3个集合,我试图通过聚合查找级联操作加入这些集合。 操作(节点类) 股票(组件类) 目录(产品类) 每个类都有一个将它们链接在一起的uuid字符串属性。 节点(传感器、接收器、基站等) 组件(带有序列号、条形码的交付产品…) 产品(市场人工制品) 在mongo shell中运行此

  • 我使用的是Spring数据jpa 1.2,但无论如何我都找不到这样的聚合查询结果。 与原生JPA完美配合 任何我的JPA存储库都是 那么,我如何才能对Spring数据进行聚合查询呢?我在文档中完全找不到任何内容