gpt4 book ai didi

java - 使用java api在elasticsearch中按结果获取多个字段组

转载 作者:行者123 更新时间:2023-12-02 09:17:17 25 4
gpt4 key购买 nike

我有一个 json

{"id": 2,"name": "Chethan","address":"Banglore"}

尝试对两个字段 id 和 name 进行分组,

List<String> statFields = new ArrayList();
statFields.add("name");
statFields.add("id");

// 2. bootstrap the query
SearchRequestBuilder search = client.prepareSearch("student")
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.matchAllQuery());

// 3. add a stats aggregation for each of your fields
for (String field : statFields) {
search.addAggregation(AggregationBuilders.terms(field+"_stats").field(field));
}

// 4. execute the query
SearchResponse response = search.execute().actionGet();

for(String field : statFields) {
Terms termAgg = (Terms) response.getAggregations().get(field+"_stats");

for (Terms.Bucket entry : termAgg.getBuckets()) {
System.out.println(entry.getKey() + " **** " + entry.getDocCount()); // Doc count
}
}

以下是回复

chethan**** 2
Raj**** 1
Mohan**** 1
1 **** 1
2 **** 1
3 **** 1

但是我需要像sql这样的组合响应,

name    id     count
chethan 1 1

是否可以通过elasticsearch java api实现

最佳答案

您应该使用 subAggregation 并使用 keyword 类型进行聚合。

Java Rest High-Level Client

假设您的映射如下所示:

PUT student
{
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"id": {
"type": "keyword"
},
"address": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}

为了分组名称id,您应该使用此查询(低级查询):

GET student/_search
{
"size": 0,
"aggs": {
"name": {
"terms": {
"field": "name.keyword",
"size": 10
},"aggs": {
"id": {
"terms": {
"field": "id",
"size": 10
}
}
}
}
}
}

在 java 中,上面的查询类似于:

SearchResponse response = client.search(new SearchRequest("student")
.source(new SearchSourceBuilder()
.size(0)
.aggregation(
AggregationBuilders.terms("by_name").field("name.keyword")
.subAggregation(AggregationBuilders.terms("by_id")
.field("id")
)
);

如果你想使用你的代码,可能是这样的:

// 2. bootstrap the query
SearchRequestBuilder search = client.prepareSearch("student")
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.matchAllQuery());

// 3. add a stats aggregation for each of your fields

TermsAggregationBuilder aggregation = AggregationBuilders.terms("name_stats").field("name.keyword");
aggregation.subAggregation(AggregationBuilders.terms("id_stats").field("id"));
search.aggregation(aggregation);


// 4. execute the query
SearchResponse response = search.execute().actionGet();


Terms termAgg = (Terms)response.getAggregations().get("name_stats");

for (Terms.Bucket entry: termAgg.getBuckets()) {
if (entry.getDocCount() != 0) {
Terms terms =entry.getAggregations().get("id");
Collection<Terms.Bucket> buckets = terms.getBuckets();
for (Bucket sub : buckets ) {
System.out.println((int) sub.getDocCount());
System.out.println(sub.getKeyAsString());
}
}
}

我删除了 for 循环。既然必须使用子聚合,您应该设计自己的结构。

更新

这是你想要的吗?

GET student/_search
{
"size": 0,
"aggs" : {
"name_id" : {
"terms" : {
"script" : {
"source": "doc['name.keyword'].value + '_' + doc['id'].value",
"lang": "painless"
}
}
}
}
}

我希望这就是您的目标。

关于java - 使用java api在elasticsearch中按结果获取多个字段组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58909061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com