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?

3
  • This answer or this other one should help. Commented Feb 24, 2016 at 6: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) Commented Feb 24, 2016 at 7:30
  • Gotcha, let's find another solution then :) Commented Feb 24, 2016 at 7:30

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

receiving Page not found on the above link.
This solution is not thread safe.
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.