spring-projects / spring-data-elasticsearch

Provide support to increase developer productivity in Java when using Elasticsearch. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-elasticsearch/
Apache License 2.0
2.92k stars 1.33k forks source link

[FEATURE] Support Search Templates via Annotation #2997

Open gquintillan opened 3 weeks ago

gquintillan commented 3 weeks ago

Elastic Search provides the Search template API which is a very clean and efficient way to run queries in ElasticSearch.

A search template is a stored search you can run with different variables.
If you use Elasticsearch as a search backend, you can pass user input from a search bar as parameters for a search template. This lets you run searches without exposing Elasticsearch’s query syntax to your users.
If you use Elasticsearch for a custom application, search templates let you change your searches without modifying your app’s code.

I checked both in the documentation and the code and I couldn't find an annotation that supports it.

They idea would be to have something like:

@Repository
public interface SampleDataRepository extends Repository<SampleData, String> {

    @SearchTemplateQuery(id="my-search-template")
    List<SampleData> findSamples(String queryString, int from, int size);

}

Which translates into this (example taken from the Elasticsearch documentation):

GET my-index/_search/template
{
  "id": "my-search-template",
  "params": {
    "queryString": "hello world",
    "from": 0,
    "size": 10
  }
}

In case it helps, without annotations we have to do it like this:

@Repository
public class SampleDataRepositoryImpl implements SampleDataRepository {

    private final ElasticsearchOperations elasticsearchOperations;

    public SampleDataRepositoryImpl(ElasticsearchOperations elasticsearchOperations) {
        this.elasticsearchOperations = elasticsearchOperations;
    }

    @Override
    public SearchHits<SampleData> findSamples(String queryString, int from, int size) {
        final Map<String, Object> templateParams = Map.of(
                "queryString", queryString,
                "from", from,
                "size", size);
        SearchTemplateQuery searchTemplateQuery = SearchTemplateQuery.builder()
                .withId("my-search-template")
                .withParams(templateParams)
                .build();
        return elasticsearchOperations.search(searchTemplateQuery, SampleData.class);
    }
}
sothawo commented 3 weeks ago

Interesting idea. Might even find some time this week to have a deeper look.

rishiraj88 commented 3 weeks ago

Very impressive and nice idea, @gquintillan ! Thanks a ton for thinking through and sharing.