How to make facet search by multiple nested fields in Elasticsearch Java API Client?

There are my example documents

"id" : "1",
"title" : "test",
"description" : "test",
"price" : 100.0,
"category_id" : "1",
"characteristics" : [
  {
    "characteristic_id" : "1",
    "text_value" : "red"
  },
  {
    "characteristic_id" : "2",
    "numeric_value" : 15
  },
  {
    "characteristic_id" : "3",
    "numeric_value" : 20
  }
]

"id" : "2",
"title" : "test",
"description" : "test",
"price" : 200.0,
"category_id" : "1",
"characteristics" : [
  {
    "characteristic_id" : "1",
    "text_value" : "blue"
  },
  {
    "characteristic_id" : "2",
    "numeric_value" : 10
  },
  {
    "characteristic_id" : "3",
    "numeric_value" : 5
  }
]

And a query to my index must be like this. How can i write this using new Java Api Client for Elasticsearch?

GET product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "characteristics",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "characteristics.characteristic_id": 1
                    }
                  },
                  {
                    "term": {
                      "characteristics.text_value": "blue"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "characteristics",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "characteristics.characteristic_id": 3
                    }
                  },
                  {
                    "range": {
                      "characteristics.numeric_value": {
                        "gte": 1,
                        "lte": 7
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "term": {
            "category_id": 1
          }
        },
        {
          "range": {
            "price": {
              "gt": 10.0,
              "lt": 500.0
            }
          }
        }
      ],
      "should": [
        {          
          "match": {
            "title": "te"
          }
        }
      ]
    }
  }
}

There is very little information in the official documentation. Should I even use this API if there is no normal documentation for it and write all the requests manually?

I wrote some tips on how to use the IDE autocompletion to help writing Java code against the Java client.

Hope this helps.

i did it.

Query characteristicQuery = NestedQuery.of(n -> n
                .path("characteristics")
                .query(q -> q
                        .bool(b -> b
                                .must(m -> m
                                        .term(t -> t
                                                .field("characteristics.characteristic_id")
                                                .value("2")
                                        )
                                ).must(m -> m
                                        .range(r -> r
                                                .field("characteristics.numeric_value")
                                                .gte(JsonData.of(1))
                                                .lte(JsonData.of(5)))))))._toQuery();


        Query termQuery = TermQuery.of(t -> t
                .field("category_id")
                .value("1"))._toQuery();

        Query priceQuery = RangeQuery.of(r -> r
                .field("price")
                .gte(JsonData.of(1.0))
                .lte(JsonData.of(500.0)))._toQuery();

        List<Query> list = new ArrayList<>();
        list.add(characteristicQuery);
        list.add(termQuery);
        list.add(priceQuery);

        BoolQuery boolQuery = BoolQuery.of(b -> b
                .filter(list)
                .should(s -> s
                        .match(m -> m
                                .field("title")
                                .query("te"))));

        SearchResponse<ProductDocument> response = esClient.search(s -> s
                        .index("product")
                        .query(q -> q.bool(boolQuery)),
                ProductDocument.class);