6

How can I parameterize a SpringData ElasticSearch index at runtime?

For example, the data model:

@Document(indexName = "myIndex")
public class Asset {

    @Id
    public String id;

    // ...
}

and the repository:

public interface AssetRepository extends ElasticsearchCrudRepository<Asset, String> {

    Asset getAssetById(String assetId);
}

I know I can replace myIndex with a parameter, but that parameter will be resolved during instantiation / boot. We have the same Asset structure for multiple clients / tenants, which have their own index. What I need is something like this:

public interface AssetRepository extends ElasticsearchCrudRepository<Asset, String> {

    Asset getAssetByIdFromIndex(String assetId, String index);
}

or this

repoInstance.forIndex("myOtherIndex").getAssetById("123");

I know this does not work out of the box, but is there any way to programmatically 'hack' it?

Daniel
  • 2,087
  • 3
  • 23
  • 37
  • [This answer](http://stackoverflow.com/questions/33894618/creating-indices-name-dynamically-in-elasticsearch-using-spring-data-elasticsear?s=1|2.2393) or [this other one](http://stackoverflow.com/questions/24333327/rolling-index-dynamic-index-name-in-spring-data-elasticsearch?s=2|2.0926) should help. – Val Feb 24 '16 at 06:54
  • I believe neither do (found and studied both before). Those are about not hard coding the index name, but I need to be able to call to many different indexes. I only know the index name via a client parameter (not at compile or boot time) – Daniel Feb 24 '16 at 07:30
  • Gotcha, let's find another solution then :) – Val Feb 24 '16 at 07:30

2 Answers2

2

Even though the bean is init at boot time, you can still achieve it by spring expression language:

@Bean
Name name() {
    return new Name();
}

@Document(indexName="#{name.name()}")
public class Asset{}

You can change the bean's property to change the index you want to save/search:

    assetRepo.save(new Asset(...));
    name.setName("newName");
    assetRepo.save(new Asset(...));

What should be noticed is not to share this bean in multiple thread, which may mess up your index.

Here is a working example.

Tony
  • 5,972
  • 2
  • 39
  • 58
0

org.springframework.data.elasticsearch.repository.ElasticSearchRepository has a method

FacetedPage<T> search(SearchQuery searchQuery);

where SearchQuery can take multiple indices to be used for searching.

I hope it answers

Rahul
  • 15,979
  • 4
  • 42
  • 63