Search code examples
springelasticsearchannotationsspring-dataspring-data-elasticsearch

aliasing with spring data elasticsearch repository search and persist conflict


i'm having aliasing conflict issues using spring-data-es,

I have a need for daily based roll-over index - A_Day1, A_Day2, ... A_now() with aliasing:

1. active_A - points to latest index - A_now()
*Persistence should be done on this alias*
2. search_A - points to all existing indexes + A_now()
*Search should be done on this alias*

My document entity holds the indexName of search_A, @Document(indexName = "search_A", indexType="..."), This causes every-time a search query is performed, either via repository (findBy....) or via ElasticTemplate.queryForPage(Query, Clazz.class) to search on this alias - and thus searching on all existing indexes, which works as expected.

Problem arise on persistent -

Using spring-data-es repository I persist entities in all of the documents-persist-life-cycle.

repository.save(Entity),

Spring-data-es will scan indexName and persist- meaning now persistence is to (search_A) alias and NOT to active_A alias- which does not work as expected.

I thought of few workaround solutions which are not elegant and wasteful IMO:

  1. Override save() step in my DAO's - then before calling repository.save - change annotation value in runtime to persistence alias, then after persistence - change it again to search alias.
  2. Change @Document(indexName=#{dynamicDailyBased()}) using spring SPEL, but then i'm still stuck with need of alias to search. as spring-data-es will need indexName for it search options.
  3. Override all search to happen in one place- then using .withIndices("alias") --> this will cause me to lose all spring repository self-impl --> tons of boilerplate code.

A similar problem is identified here - How to interact with elastic search Alias using Spring data but I am looking for a solution which is not overriding/making custom implementation as this would be too much for not using given repository methods.

Looking for a better solution if possible or an insight to change my design / idea :)


Solution

  • I think, that third way is the most elegant one, just need to do it the Spring way.

    Create new class AbstractElasticsearchRepositoryEx, which extends AbstractElasticsearchRepository and then register it as overridden base class for ES repositories in config file:

    <elasticsearch:repositories base-package="com.amco.db.repository.elasticsearch" base-class="com.amco.db.repository.elasticsearch.AbstractElasticsearchRepositoryEx"/>
    

    Now we could override any repository method, that we want to extend logic, e.g. save(). We could determine inside, which type of Document we received in that method and choose the way of execution - special for that Document, which should be persistent using active_A alias, and regular for any other one.

    Here the link to official documentation about it: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#repositories.customize-base-repository