有没有办法让 spring-data-elasticsearch 为多租户应用程序工作?
我已经让它在没有多租户的情况下工作,但我不知道如何为每个租户拥有多个索引或多个节点?我想知道是否有任何方法可以为每个租户定义不同的索引名称或在我的实体类中添加瞬态属性,该属性用@Document(...)
. 当我试图做这个问题时,@Transient
它也被标记在ElasticSearchRepository
. 任何想法?
有没有办法让 spring-data-elasticsearch 为多租户应用程序工作?
我已经让它在没有多租户的情况下工作,但我不知道如何为每个租户拥有多个索引或多个节点?我想知道是否有任何方法可以为每个租户定义不同的索引名称或在我的实体类中添加瞬态属性,该属性用@Document(...)
. 当我试图做这个问题时,@Transient
它也被标记在ElasticSearchRepository
. 任何想法?
这是我对这个问题所做的解决方案。默认情况下,我们会添加一个带有 POJO 注释的索引,@Document
这是可以的。但是在某些情况下,我们希望每个客户端有不同的索引,所以我决定自己创建它们。我使用 ElasticSearch 模板为不同的租户创建索引,而不是依赖 Spring Data ElasticSearch repo 进行保存。这就是我所做的
IndexQuery indexQuery = new IndexQueryBuilder()
.withId("ID")
.withIndexName("yourtenant")
.withType("yourtype")
.withObject(obj)
.build();
es.index(indexQuery)
首先,您必须了解 Elasticsearch(尤其是 Lucene)如何存储您的数据。
Elasticsearch 的命名约定“index”和“type”有点误导,很可能不是你最初想的那样!
如果您id, field1, field2
在 Elasticsearch 的索引中创建类型 ( ),它将创建类似于 SQL 表的内容:
id | field1 | field2
-------------------------
string | int | boolean
您可能没想到的是,当您id, type2field
向该索引添加第二种类型 ( ) 时会发生什么。索引映射将变为:
id | field1 | field2 | type2field
--------------------------------------
string | int | boolean | string
发生这种情况是因为没有类型映射——即使 Elasticsearch 会让它看起来像那样。只有索引级别的映射!这样,您很可能最终会有很多空字段。
虽然一般来说,特别是对于多租户设置,您应该为每个类创建一个索引-而不是类型!您应该使用类型来分隔相似形状的数据,即为您的租户使用类型。或者在您的映射中添加一个附加字段以识别租户。
在此处阅读更多信息:https ://www.elastic.co/guide/en/elasticsearch/guide/current/mapping.html#_type_takeaways
我已经解决了这个问题。这可能不是最好的解决方案,但我没有找到其他任何东西。我已将字段添加tenantName
到我的索引类并用注释@javax.persistence.Transient
而不是@org.springframework.data.annotation.Transient
. 之后,我将进行搜索查询,条件是租户必须是当前用户所属的租户。
我找到了一个非常简单的 SpEL 解决方案,用于为索引添加前缀,例如
@Document(indexName = "#{@prefixProvider.getPrefix()}_foo", type="bar")
prefixProvider
只是一个普通的春豆。