Search code examples
javaspringelasticsearchelastic-stack

Convert Elastic Search Query into Java


I have written an elastic query and it's working completely fine(verified in Kibana). But I have to call this query in java to convert it. I am trying to do it using the repository Query method. But its giving me error while compilation only. Please suggest the correct way to do it.

Error: Reason: No property searchLocationOnLevel found for type LocationSearch!; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property searchLocationOnLevel found for type LocationSearch!

Elastic Query(Working)

GET dev_skp_location/_search
{
  "query": {
     "bool":{
        "must":[
        {
          "regexp": { "name": ".*pur*"}
        },
        {
          "nested": {
          "path": "locationType",
          "query": {
            "bool": {
              "must": [
                { 
                  "match": { "locationType.level": "1" } 
                  
                }]
              }
            },
          "score_mode": "avg"
        }
      }
    ]
  }
 }
}

The JPA way I am implemented it.

 @Query("{\n" +
            "     \"bool\":{\n" +
            "        \"must\":[\n" +
            "        {\n" +
            "          \"regexp\": { \"name\": \".*pur*\"}\n" +
            "        },\n" +
            "        {\n" +
            "          \"nested\": {\n" +
            "          \"path\": \"locationType\",\n" +
            "          \"query\": {\n" +
            "            \"bool\": {\n" +
            "              \"must\": [\n" +
            "                { \n" +
            "                  \"match\": { \"locationType.level\": \"1\" } \n" +
            "                  \n" +
            "                }]\n" +
            "              }\n" +
            "            },\n" +
            "          \"score_mode\": \"avg\"\n" +
            "        }\n" +
            "      }\n" +
            "    ]\n" +
            "  }\n" +
            " }")
    Page<LocationSearch> searchLocationOnLevel(String loc, String level, Pageable pageable);

Solution

  • I was able to figure out later how to do it, but I still feel JPA should have worked too. Anyone who has a better explanation for this is most welcome.

    I wrote a Query Builder method and called by using normal Elastic Search Query Methods.

    public Query AutoCompleteLocationQueryBuilder(String locationTerm, String level, Long tenantId){
    
            QueryBuilder tenantQuery = QueryBuilders
                    .matchQuery("tenantId", tenantId);
    
            String regexExpression = ".*" + locationTerm + "*";
            QueryBuilder regexQuery = QueryBuilders.regexpQuery("name",regexExpression);
    
            String nestedPath="locationType";
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            MatchQueryBuilder matchQuery =
                    QueryBuilders.matchQuery("locationType.level", level);
    
            NestedQueryBuilder nestedQuery = QueryBuilders
                    .nestedQuery(nestedPath, boolQueryBuilder.must(matchQuery), ScoreMode.Avg);
    
            QueryBuilder finalQuery = QueryBuilders.boolQuery()
                    .must(tenantQuery)
                    .must(regexQuery)
                    .must(nestedQuery);
    
            return new NativeSearchQueryBuilder()
                    .withQuery(finalQuery)
                    .build()
                    .setPageable(PageRequest.of(0, 10));
        }