Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interact with elastic search Alias using Spring data

Hi I am using elastic search Spring data. Domain structure of my project keeps on changing.So I have to drop the index in order to change the mapping every time. To overcome this problem, I am using Aliases. I created an Alias using:

elasticsearchTemplate.createIndex(Test.class);
elasticsearchTemplate.putMapping(Test.class);

    String aliasName = "test-alias";
    AliasQuery aliasQuery = new AliasBuilder()
            .withIndexName("test")
            .withAliasName(aliasName).build();

    elasticsearchTemplate.addAlias(aliasQuery);

I have a test class:

import org.springframework.data.annotation.Id
import org.springframework.data.elasticsearch.annotations.Document
import org.springframework.data.elasticsearch.annotations.Field
import org.springframework.data.elasticsearch.annotations.FieldIndex
import org.springframework.data.elasticsearch.annotations.FieldType
import org.springframework.data.elasticsearch.annotations.Setting


@Document(indexName = "test", type = "test")
@Setting(settingPath = 'elasticSearchSettings/analyzer.json')
class Test  extends BaseEntity{

@Id
@Field(type = FieldType.String, index = FieldIndex.not_analyzed)
String id

@Field(type = FieldType.String, index = FieldIndex.analyzed, indexAnalyzer = "generic_analyzer", searchAnalyzer = "generic_analyzer")
String firstName



}

TestRepository Class:

package com.as.core.repositories

import com.as.core.entities.Test
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository

interface TestRepository extends ElasticsearchRepository<Test, String>          
{


}

My question is how can I read from alias instead of the index itself? Does write operation also takes place on alias. I have looked at following link: https://www.elastic.co/guide/en/elasticsearch/guide/current/index-aliases.html#index-aliases It says that we will have to interact the alias instead of the actual index.How to achieve this using Elasticsearch Spring data Java API.

like image 904
Richa Avatar asked Aug 14 '15 17:08

Richa


1 Answers

I have worked around this limitation by using the ElasticsearchTemplate in the repository class associated with the object (although it would be much nicer if there was a way to specify an alias name on the entity itself).

The way it works is to create a custom repository interface. In your case it would be TestRepositoryCustom:

public interface TestRepositoryCustom
{
    Test> findByCustom(...);
}

Then implement this interface appending 'Impl' to the end of the base repository name:

public class TestRepositoryImpl implements TestRepositoryCustom
{
    Page<Test> findByCustom(Pageable pageable, ...)
    {
        BoolQueryBuilder boolQuery = new BoolQueryBuilder();
        FilterBuilder filter = FilterBuilders.staticMethodsToBuildFilters;
        /*
         * Your code here to setup your query
        */

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder().withQuery(boolQuery).withFilter(filter).withPageable(pageable); 

        //These two are the crucial elements that will allow the search to look up based on alias
        builder.withIndices("test-alias");
        builder.withTypes("test");

        //Execute the query
        SearchQuery searchQuery = builder.build();
        return elasticSearchTemplate.queryForPage(searchQuery, Test.class);
    }
}

Finally in your base JPA repsitory interface, TestRepository, extend the TestRepositoryCustom interface to get access to any methods on your custom interface from your repository bean.

public interface TestRepository extends ElasticsearchRepository<Consultant, String>, TestRepositoryCustom
{
}

What I would really like to see is an annotation on the entity like:

@Document(aliasName="test-alias")

This would just work in the background to provide searching on this index out of the gate so that all the jpa queries would just work regardless of the index name.

like image 160
Tim Schimandle Avatar answered Sep 20 '22 22:09

Tim Schimandle