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.
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.