opensearch-project / opensearch-project/opensearch-java

[BUG] Generic Client with Custom Deserializer fails to deserialize aggregations

Open
#1,445 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.