opensearch-project / opensearch-project/opensearch-java
[BUG] Generic Client with Custom Deserializer fails to deserialize aggregations
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 165
- Forks
- 250
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 26
Description
What is the bug?
I am using opensearch-java client 2.12.0
Describe the issue:
I have a specific requirement where I will be using aggregations on a index, but I want to use SQL plugin for that. Since the response for the aggregations from OpenSearchClient is very complicated.
I am trying to deserialize the response but getting below error:
Exception in thread "main" jakarta.json.stream.JsonParsingException: Property name 'year' is not in the 'type#name' format. Make sure the request has 'typed_keys' set.
final String body = response.getBody().map(org.opensearch.client.opensearch.generic.Body::bodyAsString).orElse("");
I get the below response as part of Response body
{"took":17,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":null,"hits":[]},"aggregations":{"year":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":1960,"doc_count":1,"COUNT(1)":{"value":0}}]}}}
Below is the code I am trying to deserialize the response
JacksonJsonpMapper jacksonJsonpMapper = new JacksonJsonpMapper();
final SearchResponse<Book> result = response.getBody().
map(b -> Bodies.json(b, SearchResponse.createSearchResponseDeserializer(Book.createBookDeserializer()), jacksonJsonpMapper))
.orElse(null);
Below is my code for the same
private static void searchUsingGenericClient(OpenSearchGenericClient openSearchGenericClient) throws IOException {
JsonObject jsonObject = Json.createObjectBuilder().add("query", "SELECT title, count(1) from books_test where year > 1951 group by year").build();
try (org.opensearch.client.opensearch.generic.Response response = openSearchGenericClient
.execute(
Requests.builder()
.endpoint("/_plugins/_sql?format=json")
.method("POST")
.json(jsonObject)
.build())) {
// Retrieve the response body as a simple string
final String body = response.getBody().map(org.opensearch.client.opensearch.generic.Body::bodyAsString).orElse("");
JacksonJsonpMapper jacksonJsonpMapper = new JacksonJsonpMapper();
final SearchResponse<Book> result = response.getBody().
map(b -> Bodies.json(b, SearchResponse.createSearchResponseDeserializer(Book.createBookDeserializer()), jacksonJsonpMapper))
.orElse(null);
System.out.println("object conversion from generic client :: " + result.hits().hits().get(0).source());
}
System.out.println("End searchUsingGenericClient :: ");
}
Do you have any additional context?
(https://forum.opensearch.org/t/generic-client-with-custom-deserializer-fails-to-deserialize-aggregations/20739)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the supplied SQL request with the generic client and inspect Bodies.json plus the SearchResponse aggregation deserializer. Compare the response's untyped aggregation key with the deserializer's expected input; done means the supplied response can be deserialized without the type#name parsing error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100