Search code examples
spring-bootelasticsearchspring-data-elasticsearchelasticsearch-java-apielasticsearch-query

Correct SearchQuery for few parameters - Elasticsearch & Spring Boot


I'm new in Elasticsearch. I'm trying to create search in Spring Boot application using ES and I stuck with queries in ES.

This is how my app looks like.

Model:

@Entity
@Document(indexName = "sport", type = "sport")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sport {

   @Id
   @GeneratedValue
   private Long id;

   @Column(length = 256)
   private String name;

}

search method in service:

@GetMapping(value = "/findSportByNameAndId/{name}/{id}")
public List<Sport> findSportByNameAndId(@PathVariable String name, @PathVariable String id){

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(matchQuery("name", name)
                    .operator(AND)
                    .fuzziness(Fuzziness.TWO)
                    .prefixLength(3))
            .withQuery(matchQuery("id", id)
                    .operator(AND))
            .build();

    List<Sport> sports = operations.queryForList(searchQuery, Sport.class);
    return sports;
}

part of ES index according the model above:

"content": [
    {
        "id": 2,
        "name": "Muay Thai"
    },
    {
        "id": 1,
        "name": "Kickboxing"
    },
    {
        "id": 3,
        "name": "Boxing"
    }
],

When I try to find something with using the name parameter it always stick to id and ignore name. Like This:

enter image description here

How SearchQuery should look like to find Sport by name within id?


Solution

  • Finally, I have realized how to solve it. In this case I need to use QueryBuilder to specify each parameter:

    @GetMapping(value = "/findSportByNameAndId/{name}/{id}")
    public List<Sport> findSportByNameAndId(@PathVariable String name, @PathVariable String id){
    
        QueryBuilder qb = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("name", name)
                        .operator(AND)
                        .fuzziness(Fuzziness.TWO)
                        .prefixLength(3)
                )
                .filter(QueryBuilders.termQuery("id", id));
    
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(qb).build();
    
        List<Sport> sports = operations.queryForList(searchQuery, Sport.class);
        return sports;
    }