opensearch-project / opensearch-java

Java Client for OpenSearch
Apache License 2.0
124 stars 183 forks source link

Terms aggregation on raw field returns Exception jakarta.json.stream.JsonParsingException: Property name 'doc_count_error_upper_bound' is not in the 'type#name' format. Make sure the request has 'typed_keys' set #613

Open rharsh-arkin opened 1 year ago

rharsh-arkin commented 1 year ago

What is the bug?

Terms aggregation on raw field returns Exception in thread "main" jakarta.json.stream.JsonParsingException: Property name 'doc_count_error_upper_bound' is not in the 'type#name' format. Make sure the request has 'typed_keys' set.

I am using Java client 2.5.0.

How can one reproduce the bug?

Create a simple index with mappings as below

{ "index1": { "mappings": { "properties": { "_all": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "fields": { "lower": { "type": "keyword", "normalizer": "lowercase_normalizer" }, "raw": { "type": "keyword", "eager_global_ordinals": true, "ignore_above": 10922 } }, "copy_to": [ "_all" ] } } } } }

Sample data

{ "took": 69, "timed_out": false, "_shards": { "total": 10, "successful": 10, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 10, "relation": "eq" }, "max_score": 1.0, "hits": [ { "_index": "index1", "_id": "5", "_score": 1.0, "_source": { "name": "name5" } }, { "_index": "index1", "_id": "3", "_score": 1.0, "_source": { "name": "name3" } }, { "_index": "index1", "_id": "9", "_score": 1.0, "_source": { "name": "MAme9" } }, { "_index": "index1", "_id": "4", "_score": 1.0, "_source": { "name": "name4" } }, { "_index": "index1", "_id": "8", "_score": 1.0, "_source": { "name": "Name8" } }, { "_index": "index1", "_id": "7", "_score": 1.0, "_source": { "name": "NAME7" } }, { "_index": "index1", "_id": "10", "_score": 1.0, "_source": { "name": "nAME10" } }, { "_index": "index1", "_id": "2", "_score": 1.0, "_source": { "name": "name2" } }, { "_index": "index1", "_id": "6", "_score": 1.0, "_source": { "name": "name6" } }, { "_index": "index1", "_id": "1", "_score": 1.0, "_source": { "name": "name1" } } ] } }

Use the below code to perform TermsAggregation

`public class EsAggregation {

public static void main(String[] args) throws Exception {
    final openSearchClient client = getClient();
    final HttpHost host = new HttpHost("localhost", 9200, "http");

    String agg = "terms.keyword";
    SearchRequest searchRequest = getSearchRequest(agg, client, "index1", rand.nextInt(10000) + "");
    SearchResponse<Object> resp2 = client.search(searchRequest, Object.class);
    System.out.println(resp2.aggregations());
    System.out.println("completed");
}

public static SearchRequest getSearchRequest(String agg, openSearchClient client, String index, String randomValue) {
    SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder().index(index);
    Aggregation aggregation;
     if (agg.equals("terms.keyword")) {
        TermsAggregation termsAggregation = new TermsAggregation.Builder().field("name.raw").showTermDocCountError(true).build();
        aggregation = new Aggregation.Builder().terms(termsAggregation).build();
    } 

    } else {
        throw new RuntimeException("Unknown agg: " + agg);
    }

    Map<String, Aggregation> map = new HashMap<String, Aggregation>();
    map.put("somename", aggregation);

    return searchRequestBuilder.aggregations(map).build();
}`

Exception reported is as below

Exception in thread "main" jakarta.json.stream.JsonParsingException: Property name 'doc_count_error_upper_bound' is not in the 'type#name' format. Make sure the request has 'typed_keys' set. at org.opensearch.client.json.ExternallyTaggedUnion$TypedKeysDeserializer.deserializeEntry(ExternallyTaggedUnion.java:132) at org.opensearch.client.opensearch._types.aggregations.MultiBucketBase.lambda$setupMultiBucketBaseDeserializer$0(MultiBucketBase.java:166) at org.opensearch.client.json.ObjectDeserializer.parseUnknownField(ObjectDeserializer.java:218) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:187) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:150) at org.opensearch.client.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:98) at org.opensearch.client.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:61) at org.opensearch.client.json.JsonpDeserializerBase$ArrayDeserializer.deserialize(JsonpDeserializerBase.java:353) at org.opensearch.client.json.JsonpDeserializerBase$ArrayDeserializer.deserialize(JsonpDeserializerBase.java:322) at org.opensearch.client.json.UnionDeserializer$SingleMemberHandler.deserialize(UnionDeserializer.java:91) at org.opensearch.client.json.UnionDeserializer.deserialize(UnionDeserializer.java:324) at org.opensearch.client.json.UnionDeserializer.deserialize(UnionDeserializer.java:279) at org.opensearch.client.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:85) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:189) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:150) at org.opensearch.client.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:98) at org.opensearch.client.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:61) at org.opensearch.client.json.ExternallyTaggedUnion$Deserializer.deserialize(ExternallyTaggedUnion.java:96) at org.opensearch.client.json.ExternallyTaggedUnion$TypedKeysDeserializer.deserializeEntry(ExternallyTaggedUnion.java:138) at org.opensearch.client.json.ExternallyTaggedUnion$TypedKeysDeserializer.deserialize(ExternallyTaggedUnion.java:121) at org.opensearch.client.json.ExternallyTaggedUnion$TypedKeysDeserializer.deserialize(ExternallyTaggedUnion.java:108) at org.opensearch.client.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:88) at org.opensearch.client.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:85) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:189) at org.opensearch.client.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:150) at org.opensearch.client.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:88) at org.opensearch.client.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:92) at org.opensearch.client.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:56) at org.opensearch.client.transport.endpoints.EndpointWithResponseMapperAttr$1.deserialize(EndpointWithResponseMapperAttr.java:69) at org.opensearch.client.transport.rest_client.RestClientTransport.decodeResponse(RestClientTransport.java:325) at org.opensearch.client.transport.rest_client.RestClientTransport.getHighLevelResponse(RestClientTransport.java:291) at org.opensearch.client.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:144) at org.opensearch.client.opensearch.opensearchClient.search(opensearchClient.java:1302)

What is the expected behavior?

No exception should be reported when showTermDocCountError is set as true.

What is your host/environment?

OS - Mac 13.5

Do you have any screenshots?

If applicable, add screenshots to help explain your problem.

Do you have any additional context?

If showTermDocCountError is set as false no exception is thrown. https://forum.opensearch.org/t/terms-aggregation-on-raw-field-is-returning-exception-in-thread-main-jakarta-json-stream-jsonparsingexception-property-name-doc-count-error-upper-bound-is-not-in-the-type-name-format-make-sure-the-request-has-typed-keys-set/15630

VachaShah commented 1 year ago

Hi @rharsh-arkin, I tried the code you posted:

SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder().index("index");

TermsAggregation termsAggregation = new TermsAggregation.Builder().field("name.raw").showTermDocCountError(true).build();
Aggregation aggregation = new Aggregation.Builder().terms(termsAggregation).build();

Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("somename", aggregation);
SearchRequest searchRequest = searchRequestBuilder.aggregations(map).build();

SearchResponse<Object> resp2 = client.search(searchRequest, Object.class);
System.out.println("Aggregations: " + resp2.aggregations().values().size());
System.out.println("completed");

And I was able to run this code without any exceptions, my output:

Aggregations: 1
completed

Let me know if I am missing something here. I ran this against opensearch-java client versions 2.5 and 2.6.