QueryBuilders.nested() in new Java REST Client works not as expected (no "nested" attribute generated), comparing to older (deprecated) HRC

The problem: I am trying to upgrade from deprecated HRC (7.13) to new REST Client 8.6 in Java.
We use nested queries, but although there is a special NestedQuery.Builder object in the new java client, its not possible to construct the same object as with an old one client.

Old HRC Java code:

BoolQueryBuilder innerQueryBuilder = ...;
QueryBuilders.nestedQuery("Addresses", innerQueryBuilder, ScoreMode.None);

It produces following JSON request:

{
  "query": {
    "nested": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "Addresses.Town": {
                  "query": "Frankfurt",
                  "operator": "AND"
                }
              }
            },
            {
              "match": {
                "Addresses.Street": {
                  "query": "Theodor",
                  "operator": "AND"
                }
              }
            }
          ]
        }
      },
      "path": "Addresses"
    }
  }
}

But if try to get the same result with the new one client - it makes no "nested" wrapping at all, although it adds necessary top level attribute name using "."

Query q = QueryBuilders.nested()
.path("Addresses")
.query(innerQueryBuilder.build()._toQuery())
.scoreMode(ChildScoreMode.None)
.build()
.query();

The result is incomplete and according current documentation not correct:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "Addresses.Town": {
                            "operator": "and",
                            "query": "Frankfurt"
                        }
                    }
                },
                {
                    "match": {
                        "Addresses.Street": {
                            "operator": "and",
                            "query": "Theodor"
                        }
                    }
                }
            ]
        }
    }
}

So am I doing something wrong or I miss something? How may I make the query really "nested" as before?

Hi @Mattteo

Try to use NestedQuery. Example:

var queryType = MatchQuery.of(ts -> ts.field("Addresses.Town").query("Frankfurt").operator(Operator.And))._toQuery();

var queryStreet = MatchQuery.of(ts -> ts.field("Addresses.Street").query("Theodor").operator(Operator.And))._toQuery();

var innerQueryBuilder = BoolQuery.of(bq -> bq.filter(queryType, queryStreet));

Query q = NestedQuery.of(n -> n.path("Address").query(innerQueryBuilder._toQuery()).scoreMode(ChildScoreMode.None))._toQuery();

var request = SearchRequest.of(s -> s.query(q));

Thanks, your example makes nested query, but please pay attention that you're using "Addresses.Street" full qualified attribute name directly. So in your example you should concatenate nested path with an attribute name manually, but its getting wrapped under "nested". In my example I do not get this wrapping, but get correct attribute concatenation. How may I get it both? The old one HLRC did not have such a problem at all, just "one-liner".

By the way - the old one client was awaiting QueryBuilder as a parameter, that was a super idea as you may easily create nested and/or boolean queries. The new one operates with complete queries only. And new Builders don't support cloning or something like .toBuilder(). Ho it is supposed to be used then?

For anyone who probably has the same problem:
it is necessary to use everywhere the method _toQuery() as it was shown above. Otherwise, if you use just .query(), it may produce incomplete result as in my first post. For me it was not obvious.

@RabBit_BR
thanks again for your complete example, it helped to understand where the problem is.

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