# SearchResponse as JSON

**URL:** <https://discuss.elastic.co/t/searchresponse-as-json/320475>\
**Category:** Elasticsearch\
**Tags:** language-clients\
**Created:** [December 5, 2022, 2:42pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475 "2022-12-05T14:42:53Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 5, 2022, 2:42pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/1 "2022-12-05T14:42:53Z")

</div>

Hi, I'm using version 8.5.1 w/ the Java client.

I'm looking for a way to get the `SearchResponse` as JSON, or at least the same output I'd get when executing the query in Kibana.

Thanks for any hints.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [December 5, 2022, 7:57pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/2 "2022-12-05T19:57:50Z")

</div>

This is how I'm doing this:

> <https://github.com/dadoonet/legacy-search/blob/06-fuzziness/src/main/java/fr/pilato/demo/legacysearch/dao/ElasticsearchDao.java#L158-L164>

This should be available in the future with:

> <https://github.com/elastic/elasticsearch-java/pull/213>
>
> This method \`serializeToString()\` helps to generate the json String representati…on of any response or request object.
> This could be useful for debugging or for other usages like consuming the search response objects within a JavaScript based frontend.

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 6, 2022, 8:32am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/3 "2022-12-06T08:32:23Z")

</div>

Thank you for your insights.

It's almost what I want. The JSON differs to the response I get via the REST API though.

here's a snippet of the response:

```auto
"sum#rxPackets": {
  "value": 1.8250254996E10
},

```

compared to

```auto
"rxBytes": {
  "value": 18250254996
},

```

with the REST API I'd get the `long` values, here I'd have to convert all the values. also the aggregation type is added, see snippets above.

Is there any way to have the JSON the same way as with the REST API response?

Thanks

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [December 6, 2022, 10:00am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/4 "2022-12-06T10:00:06Z")

</div>

@swallez Do you know? Is there a way to get at least the same "value"?

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 6, 2022, 2:24pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/5 "2022-12-06T14:24:31Z")

</div>

that would be great!

I'm experiencing strange things.

For now I tried using `Double.valueOf(valueAsText).longValue()` .

But I realised that this is not correct. Up front, when running the same query in Kibana I don't have any problems, the results are fine.

I have to strike out a bit.

I calculate a hash (long) value of a unique string (serial number of a device, which can be anything in A-Z0-9), and index the hash as `long` value. I use this hash as field for a `histogram` aggregation.

When processing the result I try to lookup the `hash` - and I'm not able to find a result.

The value I index: `-4872811286368342000`  
The value I parse: `-4872811286368342016`, from text: `-4.872811286368342E18` (this is what I get from the `SearchResponse`)

```auto
"aggs": {
  "devices": {
    "histogram": {
      "field": "serialHash",
      "interval": 1,
      "min_doc_count": 1
    },
    ...
}

```

Any idea would be much appreciated. Thanks

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 6, 2022, 2:37pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/6 "2022-12-06T14:37:07Z")

</div>

You can remove the aggregation type from the serialized string using these instructions: [Serializing aggregations and suggestions without typed keys | Elasticsearch Java API Client [8.5] | Elastic](https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/serialize-without-typed-keys.html)

Regarding the `sum` aggregation result, the Java client assumes this aggregation's result is a `double`.

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 6, 2022, 2:53pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/7 "2022-12-06T14:53:14Z")

</div>

Ok thanks.

and regarding the `histogram` aggregation, do you have any ideas?

the indexed field is of type `long`, but the result also seems to be assumed `double`, or at least I get the exponential writing. The result in Kibana is correct though.

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 6, 2022, 4:04pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/8 "2022-12-06T16:04:25Z")

</div>

Can you expand on the `long` issue in histograms? Where does `valueAsText` come from in `Double.valueOf(valueAsText).longValue()`?

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 8:25am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/9 "2022-12-07T08:25:40Z")

</div>

Of course.  
I index the value as `long`, and do a `histogram` on that field, and what I get back in the `SearchResponse` is

```auto
"doc_count": 3600,
"key": -1.49437614230614451E18

```

getting the value from the `key` from the SearchResponse as JSON `asText` or `asDouble` gives me the same `long` value, but the `value` is not the same as I index.

When querying via Kibana I get the correct `long` value as key for my histogram.

> [@divadpoc](#):
>
> The value I index: `-4872811286368342000`  
> The value I parse: `-4872811286368342016`

I don't understand why I get a different value with Java than with Kibana. I would have hoped that when I do a histogram on `long` values the same value is put into the response as key.

I hope I was able to describe my problem properly.  
Thanks

_Edit_

I just double checked the `SearchResponse` object before converting it to JSON, and at that point I already have the `double` values for the keys in question, so even for a histogram on long values the Java API gives me a double value as key, and this one is not the same as I index

What I quite don't understand is why I get the correct values when using Kibana.

And why is even the `sum` aggregation handled differently? (but that's just a minor _problem_/_concern_

---

<div class="post-metadata">

**Author:** ![Christian\_Dahlqvist](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/christian_dahlqvist/32/4617_2.png) [@Christian\_Dahlqvist](https://discuss.elastic.co/u/Christian_Dahlqvist)\
**Post date:** [December 7, 2022, 9:08am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/10 "2022-12-07T09:08:34Z")

</div>

I wonder if this is [a result of limits to JSON precision](https://stackoverflow.com/questions/15869275/json-not-converting-long-numbers-appropriately) and differences in the libraries used to create/parse the JSON?

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 9:30am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/11 "2022-12-07T09:30:12Z")

</div>

It's already in the `SearchResponse` before anything gets converted. and what I get with the java-api, and, the result w/ Kibana is fine.  
I'm really curious why the `key` of the `histogram` (which is of type `long`), is _converted_ to `double`, or _treated_ as `double`, before sending it back to the client.  
a `double` would still be fine, if the conversion to `long` would be the same value as the _original_.

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 7, 2022, 10:16am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/12 "2022-12-07T10:16:00Z")

</div>

Can you provide a code snippet showing how you do the number conversion? The precision loss may happen there.

Histogram keys are computed as `double` values in the Elasticsearch server, i.e. they cannot represent integer values larger than 2^53 without precision loss. In your case `-4872811286368342000` uses 63 bits. If we consider this number without the trailing `000`, then `-4872811286368342` fits in 53 bits, which is the limit of the precision loss. So depending on how the JSON library formats/parses this value and converts it to a `long` (i.e. extends with leading zeros or uses base-2 arithmetic) we may have different results.

That is to say that although we may find a solution for this particular case, using large integer values in JSON is prone to this kind of rounding errors, depending on how the JSON is created/processed.

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 10:56am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/13 "2022-12-07T10:56:18Z")

</div>

well, this is what I do:

I get the `SearchResponse` from `client.search(...)`, this result I convert to Json as David showed me above:

> [@dadoonet](#):
>
> [legacy-search/src/main/java/fr/pilato/demo/legacysearch/dao/ElasticsearchDao.java at 06-fuzziness · dadoonet/legacy-search · GitHub](https://github.com/dadoonet/legacy-search/blob/06-fuzziness/src/main/java/fr/pilato/demo/legacysearch/dao/ElasticsearchDao.java#L158-L164)

With Jackson library I read the nodes, and get they value for the histogram key via `Double d = node.get("key").asDouble();` and then I do `d.longValue()` (standard Java).

I also tried

```auto
String keyAsText = node.get("key").asText(); 
Double.valueOf(keyAsText).longValue()

```

that's all I do. But there. must be something different than you do when you return the result via REST? as Kibana shows the corret `long` value.

Please let me know if you need anything else.

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 7, 2022, 11:20am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/14 "2022-12-07T11:20:25Z")

</div>

Why do you serialize the response to a string, and then parse it into a JSON tree to get the information you need? What prevents you from using the response object directly?

Something like `response.aggregations().get("devices").histogram().buckets().array().get(0).key()`

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 11:24am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/15 "2022-12-07T11:24:46Z")

</div>

the reason is just b/c I forward the result to another service which handles the JSON result and doesn't know about ES specific classes.

and even with your suggestion it's a double what I get from the SearchResponse, so I'm stuck there too

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 11:47am UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/16 "2022-12-07T11:47:55Z")

</div>

I think I'll update my mappings and use `int` for my hash.

I thought with histograms on a field w/ a `numeric` type there is no calculation needed for the key, as I thought the key is just the value of the field itself. I guess this is wrong?

Still what confuses me is that I get the correct values in Kibana! Do you have any explanation why?

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 7, 2022, 2:28pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/17 "2022-12-07T14:28:03Z")

</div>

Ok, I understand now. Here's a way to get the response result in its raw binary form. It uses some lower level abstractions of the Java client, namely the transport that processes http requests and response, and endpoints that define, for each API endpoint, how to serialize requests and deserialize responses.

The trick is to wrap the `_search` endpoint into an endpoint that returns a raw binary response.

We will add this as an out-of-the-box feature of the Java client in a future release.

```java
// Create the search request
SearchRequest request = SearchRequest.of(b -> b...);

// Create a binary endpoint from the regular search endpoint. It will not deserialize
// the response and instead will just return the raw response input stream.
SimpleEndpoint<SearchRequest, ?> endpoint = SearchRequest._ENDPOINT;

BinaryEndpoint<SearchRequest> binarySearchEndpoint = new BinaryEndpoint<>(
    endpoint.id(),
    endpoint::method,
    endpoint::requestUrl,
    endpoint::queryParameters,
    endpoint::headers,
    endpoint.hasRequestBody(),
    null
);

// Force typed_keys to false, so that aggregations names do not hold type information
TransportOptions options = esClient._transportOptions().toBuilder()
    .setParameter("typed_keys", "false")
    .build();

// Call Elasticsearch by providing the transport the request and endpoint
BinaryResponse binaryResponse = esClient._transport().performRequest(request, binarySearchEndpoint, options);

// Do something with the response
System.out.println("Response = " + IOUtils.toString(binaryResponse.content(), StandardCharsets.UTF_8));

```

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 7, 2022, 2:34pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/18 "2022-12-07T14:34:16Z")

</div>

**Edit:** I added transport options with `typed_keys=false` in the code snippet above.

---

<div class="post-metadata">

**Author:** ![divadpoc](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/divadpoc/32/97844_2.png) [@divadpoc](https://discuss.elastic.co/u/divadpoc)\
**Post date:** [December 7, 2022, 6:53pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/19 "2022-12-07T18:53:44Z")

</div>

Thanks. this is neat as well.

As the issue w/ the double/long precision issue I know use Murmur3 hashing to get an int, instead of the CityHash long. This now works as expected.

---

<div class="post-metadata">

**Author:** ![swallez](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swallez/32/11972_2.png) [@swallez](https://discuss.elastic.co/u/swallez)\
**Post date:** [December 7, 2022, 7:29pm UTC](https://discuss.elastic.co/t/searchresponse-as-json/320475/20 "2022-12-07T19:29:07Z")

</div>

Awesome!

[Next page](https://discuss.elastic.co/t/searchresponse-as-json/320475.md?page=2)
