# Search elasticsearch with java client using JSON query

**URL:** <https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329>\
**Category:** Elasticsearch\
**Created:** [February 8, 2017, 7:40am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329 "2017-02-08T07:40:30Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 7:40am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/1 "2017-02-08T07:40:30Z")

</div>

Hi, I am using ElasticSearch 5.1.1

I am using the below java code to fetch data from ES :

SearchResponse response = client.prepareSearch()  
.setIndices("myindex01")  
.setTypes("iis-log")  
.setQuery(QueryBuilders.termQuery("status", "404"))   
.execute().actionGet();

But, I want to use the following JSON quey instead:

String jsonQuery = "{"query": {"term" : { "status": "404" }}}";

What code changes I need to do?

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 8, 2017, 8:02am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/2 "2017-02-08T08:02:31Z")

</div>

is javax.ws.rs.client package to publish a es url available

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 8:32am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/3 "2017-02-08T08:32:10Z")

</div>

It's an elasticsearch Transport client. You need to initialize it like below:

import org.elasticsearch.client.transport.TransportClient;  
import org.elasticsearch.common.settings.Settings;  
import org.elasticsearch.common.transport.InetSocketTransportAddress;

Settings settings = Settings.builder()  
.put("[cluster.name](http://cluster.name)", "my\_cluster").build();  
TransportClient client = new PreBuiltTransportClient(settings)  
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getLocalHost(),9300));

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 8, 2017, 8:35am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/4 "2017-02-08T08:35:32Z")

</div>

yeah, this is ES-java TransportClient API. is this what you want?

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 8:39am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/5 "2017-02-08T08:39:11Z")

</div>

Yes. I have used elasticsearch Transport client. But, my question was different.

I want to use the JSON query while fetching the ES db using java client. Any suggestion on that?

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 8, 2017, 9:00am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/6 "2017-02-08T09:00:55Z")

</div>

It means you want build a query JSON first? you could try this :

import org.elasticsearch.common.xcontent.XContentBuilder;  
import org.elasticsearch.common.xcontent.XContentFactory;

//{"query": {"term" : { "status": "404" }}}"  
XContentBuilder query = XContentFactory.jsonBuilder();  
query.startObject()  
.startObject("query").startObject("term").field("status", "404").endObject()  
.endObject();  
System.out.println(query.string());  
//{"query":{"term":{"status":"404"}}}  
client.prepareSearch("index").setQuery(query).execute().actionGet();

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 9:10am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/7 "2017-02-08T09:10:54Z")

</div>

I don't want to build a json query.  
I have already some json queries. I just want to use them directly.

I was using this with ES 1.4.2 and it was working:

SearchResponse response= client.prepareSearch(indicesToSearch).setSource(query)  
.execute().actionGet();  
// **query = Query string in JSON format**

But this code is no more working with ES 5.1.1. Hence looking for solutions.

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 8, 2017, 9:19am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/8 "2017-02-08T09:19:49Z")

</div>

The API has changed in 5.x like this：

//public SearchRequestBuilder setSource(SearchSourceBuilder source) {...}

SearchSourceBuilder source = new SearchSourceBuilder()  
.query(termQuery("field1", "test"))  
.highlighter(highlight().field("field1", 100, 0).order("score").preTags("").postTags(""));  
SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get();

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 9:23am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/9 "2017-02-08T09:23:26Z")

</div>

So, can't we use a JSON query string anymore in ES 5.X ?

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 8, 2017, 9:28am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/10 "2017-02-08T09:28:43Z")

</div>

currently I have not seen the relative APIs

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 8, 2017, 9:33am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/11 "2017-02-08T09:33:13Z")

</div>

Ok..

I was trying it like this:

String jsonQuery = "{"query": {"term" : { "status": "404" }}}";  
//QueryBuilder query = ?? (code to convert json string to queryBuilder object)

SearchResponse response =   
client.prepareSearch()  
.setIndices("myindex")  
.setTypes("log-type")  
.setSearchType(SearchType.QUERY\_AND\_FETCH)  
.setQuery( **query** ) //query is of type QueryBuilder  
.execute().actionGet();

But not able to covert the json-string to QueryBuilder object properly. Can you help me on this?

---

<div class="post-metadata">

**Author:** ![jprante](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jprante/32/44941_2.png) [@jprante](https://discuss.elastic.co/u/jprante)\
**Post date:** [February 8, 2017, 7:19pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/12 "2017-02-08T19:19:48Z")

</div>

You can use the following code fragment:

```auto
String content = "{\"query\":{\"match_all\":{}}}";

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
try (XContentParser parser = XContentFactory.xContent(content).createParser(content)) {
    QueryParseContext context = new QueryParseContext(searchModule.getQueryParserRegistry(), parser,
            new ParseFieldMatcher(true));
    searchSourceBuilder.parseXContent(context, searchModule.getAggregatorParsers(),
            searchModule.getSuggesters(), searchModule.getSearchExtRegistry());
}

SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(client(), SearchAction.INSTANCE);
SearchResponse searchResponse = searchRequestBuilder.setSource(searchSourceBuilder)
        .execute().actionGet();

```

---

<div class="post-metadata">

**Author:** ![wenpos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wenpos/32/15326_2.png) [@wenpos](https://discuss.elastic.co/u/wenpos)\
**Post date:** [February 9, 2017, 12:02am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/13 "2017-02-09T00:02:04Z")

</div>

will this works?  
TermQueryBuilder query = QueryBuilders.termQuery("status", "404");

---

<div class="post-metadata">

**Author:** ![anisen](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@anisen](https://discuss.elastic.co/u/anisen)\
**Post date:** [February 9, 2017, 5:23am UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/14 "2017-02-09T05:23:45Z")

</div>

Hi,

I used this code. I think it's fetching records for all records in ES DB. How to specify the index here?

---

<div class="post-metadata">

**Author:** ![schulm](https://avatars.discourse-cdn.com/v4/letter/s/919ad9/32.png) [@schulm](https://discuss.elastic.co/u/schulm)\
**Post date:** [February 15, 2017, 2:28pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/15 "2017-02-15T14:28:10Z")

</div>

Hi Jörg,  
this snippet doesn't work in ES 5.2.0. The Createparser method needs an additional NamedXContentRegistry. Also getQueryParserRegistry() doesn't exist anymore and the parseFieldMatcher is deprecated and will possibly break in the future.  
I think it should be possible to query a json query with the offical api without touching the ES internals.

---

<div class="post-metadata">

**Author:** ![jprante](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jprante/32/44941_2.png) [@jprante](https://discuss.elastic.co/u/jprante)\
**Post date:** [February 15, 2017, 9:26pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/16 "2017-02-15T21:26:35Z")

</div>

Here is an update for current ES API on master (untested)

```auto
String content = "{\"query\":{\"match_all\":{}}}";
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                .createParser(NamedXContentRegistry.EMPTY, content)) {
    searchSourceBuilder.parseXContent(new QueryParseContext(parser));
}
SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(client, SearchAction.INSTANCE);
SearchResponse searchResponse = searchRequestBuilder.setSource(searchSourceBuilder)
            .execute().actionGet();

```

The idea is to peek into the source code and see how `RestSearchAction` works. `RestSearchAction` must always translate an external JSON string into ES SearchRequest Java API. Unwrapping the code paths around RestSearchAction, and following a pattern where XContentParser runs over the JSON string and passes the result to the SearchSourceBuilder method that accepts XContent should do the trick. The example is of course a simplification and can not handle all real-world queries.

Your mileage may vary if you need to deal also with custom query/aggregations plugins, they have to be registered via SearchModule, and plugins might bring in other complications. For instance, `"ext": { ... }` won't work, see `SearchExtBuilder`. The ES developers have added some data binding features to XContent API, but I assume `NamedXContentRegistry.EMPTY` is safe as long as only ordinary JSON-encoded queries are parsed.

---

<div class="post-metadata">

**Author:** ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)\
**Post date:** [February 15, 2017, 11:48pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/17 "2017-02-15T23:48:32Z")

</div>

> [@jprante](#):
>
> createParser(NamedXContentRegistry.EMPTY, content)

Unfortunately NamedXContentRegistry.EMPTY doesn't work for parsing QueryBuilders without registering the built-in queries first, but they should be available through `searchModule.getNamedXContents()`. So to create the parser in the above example you can use

```auto
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                        .createParser(new NamedXContentRegistry(searchModule.getNamedXContents()), content)) {
            searchSourceBuilder.parseXContent(new QueryParseContext(parser));
}

```

---

<div class="post-metadata">

**Author:** ![javanna](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/javanna/32/4698_2.png) [@javanna](https://discuss.elastic.co/u/javanna)\
**Post date:** [February 17, 2017, 3:09pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/18 "2017-02-17T15:09:56Z")

</div>

I don't understand what the need is for using the java api, yet sending json requests that are manually handled. The java api helps sending request and composing them using its own objects. I would recommend to move over to the low level rest client for these cases where json is sent instead.

Query parsing was moved to the coordinating node with 5.0 and the java api must now send parsed objects. I wouldn't recommend doing the parsing on the client side, that is a work-around that may not work in the future. The on thing that should work though is using WrapperQueryBuilder, which allows to provide a query (not the whole search request, only the query part of it) as a string, and its parsing is actually performed on the data nodes rather than on the coordinating node.

---

<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:** [March 17, 2017, 3:10pm UTC](https://discuss.elastic.co/t/search-elasticsearch-with-java-client-using-json-query/74329/19 "2017-03-17T15:10:02Z")

</div>

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