How to have a different Elastic Spring Data index per request

251 Views Asked by At

I have a SpringMvc @RestController with an indexing function.

I want a different index to be used according to the request. For example if the request parameter is "en" then the index to be used will be that. I am trying to make a multilingual index with a different analyzer per language.

As far as I have seen , I need to annotate (I am only using Java Config) my POJO with

@Document(index="en")

but how do I manage that real-time?

1

There are 1 best solutions below

0
On

Option 1. ES Java client API.

You need to do it manually with ElasticsearchClient (ES Java client API). The ElasticsearchRepository and ElasticsearchTemplate do not support this.

Option 2. SpEL in the index name.

You can use SpEL in the index name, but you have to create indices per language yourself (e.g. on application start).

@Document(index="mydoc-#{@myLocaleService.currentLocale}")
@Settings("myindex-settings.json")
public class MyDoc {
  String id;
  Locale locale;
  String content;
}

@Service
MyLocaleService {
  public Locale getCurrentLocale() { return LocaleContextHolder.getLocale(); }
}

interface MyDocRepository extends ElasticsearchRepository<MyDoc, String>() {
}

@Service
MyDocService {

  @Autowired MyDocRepository repository;

  public void saveToIndex(MyDoc entity){
    try { 
       LocaleContext savedLocaleCtx = LocaleContextHolder.getLocaleContext();
       LocaleContextHolder.setLocale(entity.getLocale());
       myDocRepo.save(entity);
    } finally {
       LocaleContextHolder.setLocaleContext(savedLocaleCtx);
    }
  }
}

Hint: Use Index templates to reuse index settings per language.

Option 3. Custom ES template.

Alternatively, implement a custom ElasticsearchOperations that would identify and create indices per language for your entities dynamically. To identify the current locale either use a special property in the entity, or LocaleContextHolder.