How to construct QueryBuilder from JSON DSL when using Java API in ElasticSearch?
Asked Answered
T

5

25

I'm using ElasticSearch as a search service in Spring Web project which using Transport Client to communicate with ES.

I'm wondering if there exists a method which can construct a QueryBuilder from a JSON DSL. for example, convert this bool query DSL JSON to a QueryBuilder.

{
    "query" : {
        "bool" : {
            "must" : { "match" : {"content" : "quick"},
            "should": { "match": {"content" : "lazy"}
        }
    }
}

I need this method because I have to receive user's bool string input from web front-side, and parse this bool string to a QueryBuilder. However it not suit to use QueryBuilders.boolQuery().must(matchQB).should(shouldQB).must_not(mustNotQB). Because we may need several must or non must query.

If there exist a method can construct a QueryBuilder from JSON DSL or there exists alternative solutions, it will much easier.

PS: I have found two method which can wrap a DSL String to a QueryBuilder for ES search. One is WrapperQueryBuilder, see details here. http://javadoc.kyubu.de/elasticsearch/HEAD/org/elasticsearch/index/query/WrapperQueryBuilder.html Another is QueryBuilders.wrapperQuery(String DSL).

Townes answered 16/9, 2014 at 2:47 Comment(0)
A
37

You can use QueryBuilders.wrapperQuery(jsonQueryString);

Amsden answered 14/1, 2015 at 20:38 Comment(1)
By omitting the {"query":} part in json string works charm !Campaign
R
11

You can use setQuery, which can receive a json format string.

/**
 * Constructs a new search source builder with a raw search query.
 */
public SearchRequestBuilder setQuery(String query) {
    sourceBuilder().query(query);
    return this;
}

Note this: only part of the DSL is needed, the {"query": } part is omitted, like this:

SearchResponse searchResponse = client.prepareSearch(indices).setQuery("{\"term\": {\"id\": 1}}").execute().actionGet();
Ryannryazan answered 16/9, 2014 at 3:23 Comment(4)
Thanks for your answer, I have found two method in ES API which can wrap DSL string to QueryBuilder, one is WrapperQueryBuilder, another is QueryBuilders.wrapperQuery()Townes
omit the {"query":} part helps me a lot, thanks again for your help.Townes
For those of you using ES 5.0, this no longer works: discuss.elastic.co/t/…Amabel
@GordonThompson exactly, for those using newer versions make sure to check the WrapperQuery.Fairweather
H
1

It might be worth investigating low level rest client. With this you can do:

RestClient esClient = RestClient.builder(new HttpHost("localhost", 9200, "http")).build();
Request request = new Request("POST", "/INDEX_NAME/_doc/_search");
request.setJsonEntity(yourJsonQueryString);

Response response = esClient.performRequest(request);

String jsonResponse = EntityUtils.toString(response.getEntity());
Haplite answered 25/6, 2019 at 14:35 Comment(0)
R
0

With RestHighLevelClient (that uses lowLevelClient())

`Request request = new Request("POST", "yourURL");
    request.setJsonEntity(yourJsonDSL);
    try {
        Response response = restHighLevelClient.getLowLevelClient().performRequest(request);
        String jsonResponse = EntityUtils.toString(response.getEntity());
        JSONObject jsonTransactionObject = new JSONObject(jsonResponse);
    } catch (IOException ex) {
                //error;
    }`
Rankins answered 28/5, 2023 at 10:59 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Ukrainian
P
0

For query (btw. original query contains errors, missing closing braces)

{
    "query" : {
        "bool" : {
            "must" : { "match" : {"content" : "quick"}},
            "should": { "match": {"content" : "lazy"}}
        }
    }
}

the solution is like below, you simply pass the value of "query" node from JSON

QueryBuilders.wrapperQuery("""
    {
        "bool" : {
            "must" : { 
                "match" : {"content" : "quick"}},
            "should": { 
                "match": {"content" : "lazy"}
            }
        }
    }
    """);
Protochordate answered 11/4 at 8:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.