Search code examples
javaspring-bootelasticsearchspring-data-elasticsearch

How to search by nested field id using NativeSearchQueryBuilder in ElasticsearchRepository?


I am using spring-data-elasticsearch and I have a class as follows,

@Document(indexName = "sample")
class Sample {

   @Id
   private String id;
   private String name;
   private Status status;
}

class Status {
   private String id;
}

Above is persisted to elasticsearch. And I have the following method to find data in it.

List<Sample> getAll(String statusId, String text, Pageable pageable);

So here is the current code I am using to get the data,

NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(text)
                        .field("name")
                        .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX));
NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();

What I need is I need to find results by statusId and then search for the texts containing in name field.

I tried the following way also but didn't work. I tried the criteria-api also but it is working for only words without space. If there is words with space it is throwing Cannot constructQuery '*\"text\"*'. Use expression or multiple clauses instead

.withFilter(QueryBuilders.termQuery("status.id", statusId))

So how can I build the query for the above scenario?

New query build after suggestions by P.J. Meisch

QueryBuilder query1 = QueryBuilders.matchQuery("status.id", statusId).operator(Operator.AND);
QueryBuilder query2 = QueryBuilders.multiMatchQuery(text).field("name").type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX);

new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(query1).must(query2));

Solution

  • Your top level query should be a bool query with two entries as must:

    • the first for the name that would be the one you already have.
    • the second for the "status.id" property