Java – how to use spring data to interact with elastic search aliases
Hi, I'm using elastic search for spring data The domain structure of my project is constantly changing So I have to delete the index to change the mapping every time To solve this problem, I am using aliases
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 to read from the alias instead of the index itself? Whether the write operation also occurs on the alias I checked the following links: https://www.elastic.co/guide/en/elasticsearch/guide/current/index-aliases.html#index -Aliases it says that we will have to exchange aliases instead of actual indexes How to use elasticsearch spring data Java API to achieve this
Solution
I solved this limitation by using elasticsearchtemplate in the repository class associated with the object (although it would be better if there was a way to specify an alias on the entity itself)
It works by creating custom repository interfaces In your case, it will be testrepository custom:
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 repository interface testrepository, extend the testrepository custom interface to access any method on the custom interface from your repository bean
public interface TestRepository extends ElasticsearchRepository<Consultant,String>,TestRepositoryCustom { }
What I really want to see is comments on entities, such as:
@Document(aliasName="test-alias")
This will work in the background to provide the ability to search this index from the door so that all JPA queries work correctly, regardless of the index name