How to interact with elastic search Alias using Spring data
Asked Answered
H

2

7

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.

Hypaethral answered 14/8, 2015 at 17:25 Comment(0)
G
10

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.

Grillo answered 18/8, 2015 at 17:3 Comment(2)
Here is an open issue for that: jira.spring.io/browse/DATAES-192Kirstenkirsteni
On the other hand, if the number of aliases is unknown at the time you create the mapping, we need something else than a annotation like you propose. For instance, if you need an alias for each users (to implement multi-tenancy). Than I would like to see something like: @Document(aliasKey="user_id") Than, you can PUT any document as the following (Spring data) could create the alias if it is not present. PUT /user123/post/1 { "user_id": "user123", "title": "Easy recipe for ginger nuts", ... }Mastery
M
1

Spring-data-elasticsearch supports finding documents in an alias. We were able to make version 3.2.6.RELEASE read documents annotated with

@Document(
    indexName = "alias",
    createIndex = false,
    type = '_doc'
)

from a Spring Data ElasticsearchRepository backed by a ElasticsearchRestTemplate

Muddleheaded answered 30/3, 2020 at 21:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.