# termsQuery no longer uses XContentWriters

**URL:** <https://discuss.elastic.co/t/termsquery-no-longer-uses-xcontentwriters/276316>\
**Category:** Elasticsearch\
**Created:** [June 17, 2021, 9:15pm UTC](https://discuss.elastic.co/t/termsquery-no-longer-uses-xcontentwriters/276316 "2021-06-17T21:15:39Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lars\_Benedetto](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/lars_benedetto/32/90494_2.png) [@Lars\_Benedetto](https://discuss.elastic.co/u/Lars_Benedetto)\
**Post date:** [June 17, 2021, 9:15pm UTC](https://discuss.elastic.co/t/termsquery-no-longer-uses-xcontentwriters/276316/1 "2021-06-17T21:15:39Z")

</div>

Between 7.9.3 and 7.12.1 it seems the way that arguments to termsQuery() are serialized have changed. In 7.9.3 it used my XContentBuilderExtension to convert my classes to strings that could be understood by elasticsearch.

But now in 7.12.1, it goes through StreamOutput which does not seem to have a way to add any customization, so it fails to serialize.

Is there a way to get it to serialize my classes correctly, or do I just have to manually serialize everything before passing it to query builders now?

I believe this issue was created by this pull request:

> <https://github.com/elastic/elasticsearch/pull/67223>
>
> \#67132 tried to cache all the results of serialization of \`SearchSourceBuilder\`,… which is invasive. So this is a patch that only aims to optimizing \`TermsQueryBuilder\`. 
> 
> Here are some benchmark results (indices and queries are the same as #67132):
> 
> \*\*No Param\*\*
> target | baseline | candidate
> \-- | -- | --
> 1 index (8 shards) | 83ms | 13ms
> 30 indices (240 shards) | 2935ms | 201ms
> 
> \*\*set pre\_filter\_shard\_size=240\*\*
> 
> target | baseline | candidate
> \-- | -- | --
> 1 index (8 shards) | 81ms | 13ms
> 30 indices (240 shards) | 731ms | 104ms

Which has spawned these two related issues:

> <https://github.com/elastic/elasticsearch/issues/73547>
>
> \*\*Elasticsearch version\*\*: 7.12.1
> 
> \*\*Description of the problem including expe…cted versus actual behavior\*\*:
> Prior to Elasticsearch 7.12.0 using terms query with an enum value was working without any issues. After upgrading java Elasticsearch client from 7.10.0 to 7.12.1 the following exception has been thrown when terms query is used for an Enum value. The same code is tested for previous versions and it works without any issues.
> 
> \`\`\`
> BoolQueryBuilder query = QueryBuilders.boolQuery();
> query.mustNot(QueryBuilders.termsQuery("foo", Thing.BAR));
> 
> public Enum Thing{
> FOO, BAR;
> 
> @Override 
> @JsonValue
> public String toString() {
> return name().toLowerCase();
> }
> }
> \`\`\`
> 
> \*\*Exception:\*\*
> \`\`\`
> Caused by: java.lang.IllegalArgumentException: can not write type \[class com.example.Thing\]
> at org.elasticsearch.common.io.stream.StreamOutput.writeGenericValue(StreamOutput.java:845)
> at org.elasticsearch.common.io.stream.StreamOutput.lambda$static$12(StreamOutput.java:700)
> at org.elasticsearch.common.io.stream.StreamOutput.writeGenericValue(StreamOutput.java:843)
> at org.elasticsearch.index.query.TermsQueryBuilder$Values.serialize(TermsQueryBuilder.java:434)
> at org.elasticsearch.index.query.TermsQueryBuilder$BinaryValues.\<init\>(TermsQueryBuilder.java:493)
> at org.elasticsearch.index.query.TermsQueryBuilder$BinaryValues.\<init\>(TermsQueryBuilder.java:483)
> at org.elasticsearch.index.query.TermsQueryBuilder.\<init\>(TermsQueryBuilder.java:161)
> at org.elasticsearch.index.query.TermsQueryBuilder.\<init\>(TermsQueryBuilder.java:141)
> at org.elasticsearch.index.query.QueryBuilders.termsQuery(QueryBuilders.java:568)
> \`\`\`
> 
> 
> Prior to 7.12.0, the same code snippet works without any issues. The workaround is to use .toString() wherever an Enum value has been used.
> 
> After exploring what could have gone wrong in the version 7.12.1 client, we realised that \[this PR\](https://github.com/elastic/elasticsearch/pull/67223) has created the mentioned side effect. The issue seems to be related to line 168 of TermsQueryBuilder.java.

> <https://github.com/elastic/elasticsearch/issues/71972>
>
> We currently have a constructor on TermsQueryBuilder that takes generic \`Object.….. values\` as argument, probably to
> facilitate creating terms queries for things like \`Date\` and \`GeoPoint\`. However we need to be able to serialize these objects via our transport
> protocol (everything that \`StreamOutput.writeGenericValue\` seems to work at least on that level), so not all Objects will work.
> We \[recently changed\](https://github.com/elastic/elasticsearch/pull/67223) the code to use this serialization alread on construction to convert values to a BytesReference.
> Before that it was possible to use the object ctor for example in the High Level Rest Client for Enums, the json serialization for the request would then convert these to their String representation behind the scenes (see #71388). This doesn't work any longe, which on one hand is a good thing because we fail early on things we later cannot serialize anyway, but also shows how misleading using this constructor can be.
> I'm opening this issue as a starting point for investigation if we can make this ctor safer, either by replacing it with a stronger typed one (and deprecate and eventually remove the existing one), or by enhancing javadocs on the ctor to avoid its wider usage except for cases where it really makes sense (i.e. Date, GeoPoint etc...).
> 
> Relates to #71388

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 15, 2021, 9:16pm UTC](https://discuss.elastic.co/t/termsquery-no-longer-uses-xcontentwriters/276316/2 "2021-07-15T21:16:23Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
