ElasticsearchRestTemplate Java聚合查询+操作索引+查询时10000条上限

分组查询


	private final ElasticsearchRestTemplate esRestTemplate;
	
	// select count(1), status from order group by status 
	public void aggregate(){
		// 查询条件
		NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
			.withQuery(
				QueryBuilders.rangeQuery("createTime")
					.format("yyyy-MM-dd HH:mm:ss")
					.gte("2021-08-17 00:00:00").lte("2021-08-18 00:00:00")
					.includeLower(true).includeUpper(true))
			// 分组查询status字段并as count
			.addAggregation(AggregationBuilders.terms("count").field("status"))	
			.withSourceFilter(new FetchSourceFilterBuilder().build())
			// 下面两行优化速度 去除查询结果 只取聚合查询的结果
			// withFields不给参数去掉dom的所有字段 & 分页只取1条
			.withFields()
			.withPageable(PageRequest.of(0, 1));

		String idx = "idx_order_dev";
		AggregatedPage<EsOrder> results = esRestTemplate.queryForPage(queryBuilder.build(), EsOrder.class, IndexCoordinates.of(idx));
		Aggregations entitiesAggregations = results.getAggregations();
		Terms terms = (Terms) entitiesAggregations.asMap().get("count");
		
		// 遍历取出聚合字段列的值,与对应的数量
		for (Terms.Bucket bucket : terms.getBuckets()) {
			String key = bucket.getKeyAsString(); // 聚合字段列的值
			long val = bucket.getDocCount();// 聚合字段对应的数量
			System.out.printf("%s -> %s\n", key, val);
		}
	
	}

索引操作

操作单条保存时 ElasticsearchRestTemplateElasticsearchRepository
因为repository会在每次保存完时刷新索引

  • 创建索引 & 字段映射
IndexCoordinates idx = IndexCoordinates.of("idx_order");
IndexOperations idxOps = esRestTemplate.indexOps(idx);
idxOps.create();
Document mapping = idxOps.createMapping(EsOrder.class);
idxOps.putMapping(mapping);
  • 删除索引(等于drop table 数据全清除)
IndexCoordinates idx = IndexCoordinates.of("idx_order_dev");
IndexOperations idxOps = esRestTemplate.indexOps(idx);
idxOps.delete();
  • 实体类
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

@Data
@Document(indexName = "idx_order_#{orderConfiguration.profile}", shards = 3, replicas = 2)
public class EsOrder extends EsOrderView implements Serializable {
	/**
	 * 订单号
	 */
	@Field(type = FieldType.Keyword)
	private String orderId;
	...
}

10000条上限

  • 查询条数限制
    query时默认上限是10000条 向ES服务器put一条设置即可修改该限制
PUT /索引名/_settings?preserve_existing=true
{"index.max_result_window":"2000000000"}
  • count限制
    使用ElasticsearchRepository或者ElasticsearchRestTemplate查询分页时,返回的total数也会限制10000,导致分页功能页面仅显示10000条。
    AbstractQuery的源码得知里面有提供字段trackTotalHits用于查询总数,但是builder类NativeSearchQueryBuilder中没有提供设值方法 我们可以在此基础上自定义一个QueryBuilder来设值进去即可。
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

/**
 * 自定义queryBuilder 在原基础上添加了trackTotalHits的配置
 * @author stark
 * @date 2021年11月29日11:32:30
 */
public class NativeSearchQueryBuilderCustom extends NativeSearchQueryBuilder{

	private Boolean trackTotalHits;

	public NativeSearchQueryBuilderCustom() {
	}

	public NativeSearchQueryBuilderCustom trackTotalHits(boolean trackTotalHits) {
		this.trackTotalHits = trackTotalHits;
		return this;
	}

	@Override
	public NativeSearchQueryBuilderCustom withFields(String... fields) {
		super.withFields(fields);
		return this;
	}

	@Override
	public NativeSearchQueryBuilderCustom withQuery(QueryBuilder queryBuilder) {
		super.withQuery(queryBuilder);
		return this;
	}

	@Override
	public NativeSearchQueryBuilderCustom withSort(SortBuilder sortBuilder) {
		super.withSort(sortBuilder);
		return this;
	}

	@Override
	public NativeSearchQueryBuilderCustom withPageable(Pageable pageable) {
		super.withPageable(pageable);
		return this;
	}

	@Override
	public NativeSearchQuery build() {
		NativeSearchQuery build = super.build();
		if(this.trackTotalHits != null){
			build.setTrackTotalHits(this.trackTotalHits);
		}

		return build;
	}
}

使用

NativeSearchQueryBuilderCustom queryBuilder = new NativeSearchQueryBuilderCustom()
			.withPageable(PageRequest.of(query.getCurrent(), query.getSize()))	// 分页
			.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))	// 排序
			.withFields(fixedEsField)	// 过滤字段
			.trackTotalHits(true);	// 查询所有数

repository.search(queryBuilder.build());
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ElasticsearchRestTemplateSpring Data Elasticsearch提供的一个Rest客户端,可以用于与Elasticsearch进行交互。要使用ElasticsearchRestTemplate进行聚合查询,需要使用Elasticsearch的聚合API。 以下是一个简单的示例,演示如何使用ElasticsearchRestTemplate进行聚合查询: ```java import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.metrics.avg.Avg; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.stereotype.Service; import java.util.Date; @Service public class AggregationService { @Autowired private ElasticsearchRestTemplate elasticsearchRestTemplate; public void aggregate() { SearchResponse response = elasticsearchRestTemplate.getClient().prepareSearch("my_index") .setQuery(QueryBuilders.matchAllQuery()) .addAggregation(AggregationBuilders.dateHistogram("histogram") .field("timestamp") .dateHistogramInterval(DateHistogramInterval.DAY) .subAggregation(AggregationBuilders.sum("sum").field("value")) .subAggregation(AggregationBuilders.avg("average").field("value"))) .execute().actionGet(); Histogram histogram = response.getAggregations().get("histogram"); for (Histogram.Bucket entry : histogram.getBuckets()) { Date date = (Date) entry.getKey(); Sum sum = entry.getAggregations().get("sum"); Avg avg = entry.getAggregations().get("average"); // Do something with the aggregations } } } ``` 在这个示例中,我们使用ElasticsearchRestTemplate执行一个聚合查询。我们首先使用`QueryBuilders.matchAllQuery()`创建一个查询,然后使用`.addAggregation()`添加一个聚合。在这个聚合中,我们使用`AggregationBuilders.dateHistogram()`创建一个日期直方图聚合,聚合字段为`timestamp`,聚合间隔为每天。我们还添加了两个子聚合,一个求和聚合和一个平均值聚合。 在执行查询后,我们从响应中获取`Histogram`对象,并遍历每个直方图目。对于每个目,我们从聚合中获取求和和平均值,并对它们进行操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值