Home > Enterprise >  ElasticSearch Convert Rest Query for nested field to client Scala/Java code
ElasticSearch Convert Rest Query for nested field to client Scala/Java code

Time:12-15

I could not find the documentation on how to transform the nested query from the ES official example into Scala/Java code

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
  }
}

In Scala I've tried

  import org.elasticsearch.index.query.QueryBuilders._
  ...

  val q = boolQuery()
  q.must(termQuery("user.first", "Alice"))
  q.must(termQuery("user.last", "White))
  nestedQuery("user", q, ScoreMode.None)
        

but when inspecting the resulted query it was not the same.

The resulting query is something similar to (cropped version of it since original query is much bigger):

 "nested" : {
                            "query" : {
                              "bool" : {
                                "must" : [
                                  {
                                    "match" : {
                                      "user.first" : {
                                        "query" : "Alice",
                                        "operator" : "OR",
                                        "prefix_length" : 0,
                                        "max_expansions" : 50,
                                        "fuzzy_transpositions" : true,
                                        "lenient" : false,
                                        "zero_terms_query" : "NONE",
                                        "auto_generate_synonyms_phrase_query" : true,
                                        "boost" : 1.0
                                      }
                                    }
                                  },
                                  {
                                    "match" : {
                                      "user.last" : {
                                        "query" : "Smith",
                                        "operator" : "OR",
                                        "prefix_length" : 0,
                                        "max_expansions" : 50,
                                        "fuzzy_transpositions" : true,
                                        "lenient" : false,
                                        "zero_terms_query" : "NONE",
                                        "auto_generate_synonyms_phrase_query" : true,
                                        "boost" : 1.0
                                      }
                                    }
                                  }
                                ],
                                "adjust_pure_negative" : true,
                                "boost" : 1.0
                              }
                            },
                            "path" : "user",
                            "ignore_unmapped" : false,
                            "score_mode" : "none",
                            "boost" : 1.0
                          }
                        }

The actual exception I am getting is in an unittest:

. java.io.NotSerializableException: org.elasticsearch.client.Response
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputSt[info] - should excluded keywords only *** FAILED ***
[info]   org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
[info]   at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:176)
[info]   at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1933)
[info]   at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1910)
[info]   at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1667)
[info]   at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1624)
ream.java:1509)
    at java.io.Obje[info]   at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1594)
[info]   at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:1110)

CodePudding user response:

Your Scala code is generating correct query. basically what happen here is, it added some default parameter with values in query and due to that, it looks like your query is bigger compare to original query. This done by both Java and Scala elasticsearch client (might be other language client is doing same). Also, when you create DSL query in Kibana, runtime this all the default parameter added to your query.

Below are the parameters with default value in your query:

"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1.0

Below I have removed all the default parameter which is added in your query by code:

{
    "nested": {
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "user.first": {
                                "query": "Alice"
                            }
                        }
                    },
                    {
                        "match": {
                            "user.last": {
                                "query": "Smith"
                            }
                        }
                    }
                ]
            }
        },
        "path": "user"
        
    }
}
  • Related