Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multitenancy with spring-data-elasticsearch

Is there any way to make spring-data-elasticsearch to work for multitenant application?

I've made it to work without multitenancy, but I don't know how can I have multiple indices or multiple nodes for each tenant? I want to know if there is any way to define different index name for each tenant or to add transient property in my entity class which is annotated properly with @Document(...). When I tried to do that problem was that @Transient is also marked in ElasticSearchRepository. Any idea?

like image 475
miroslav_mijajlovic Avatar asked Mar 14 '14 10:03

miroslav_mijajlovic


2 Answers

Here's the solution I made to this problem. By default, We would add an index with our POJO annotation of @Document which is okay.However there are cases where we would want to have differen indexes per client so I decided to create them myself. I've used the ElasticSearch Template to create indexes for different tenants rather than relying on Spring Data ElasticSearch repo for saving. Here's what I did

    IndexQuery indexQuery = new IndexQueryBuilder()
                        .withId("ID")
                        .withIndexName("yourtenant")
                        .withType("yourtype")
                        .withObject(obj)
                        .build();

    es.index(indexQuery)
like image 197
KyelJmD Avatar answered Oct 15 '22 14:10

KyelJmD


First you've got to understand how Elasticsearch (and especially Lucene) store your data.

Elasticsearch's naming convention "index" and "type" is a bit misleading and most likely not what you first thought!


If you create a type (id, field1, field2) within an index in Elasticsearch, it will create something similar to a SQL Table:

id     | field1 | field2
-------------------------
string | int    | boolean

What you might not expect is, what happens when you add a second type (id, type2field) to that index. The index mapping will become:

id     | field1 | field2  | type2field
--------------------------------------
string | int    | boolean | string

This happens, because there's no type mapping - even if Elasticsearch will make it look like that. There's only a mapping at index level! This way, you will most likely end up having a lot of empty fields.


Though in general and especially for a multi tenency setup, you should create an index per class - not type! You should use the type for separating similar shaped data, i.e. use types for your tenants. Or add an additional field to your mapping for identifying the tenant.


Read more about it here: https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping.html#_type_takeaways

like image 37
Benjamin M Avatar answered Oct 15 '22 13:10

Benjamin M