Spring Data MongoDB基于集合的多租户 [英] Collection based multitenancy with Spring Data MongoDB

查看:299
本文介绍了Spring Data MongoDB基于集合的多租户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的Spring Boot 1.3.3应用程序使用Spring Data MongoDB 1.8.4将数据持久存储在MongoDB(2.6或3.2)上.

Our Spring Boot 1.3.3 application persists data on MongoDB (2.6 ou 3.2) using Spring Data MongoDB 1.8.4.

我们需要支持多租户.我们选择使用基于集合"的多租户,即每个租户都有自己的集合.例如,对于Article实体,集合是"{tenantName} _articles".

We need to support multitenancy. We chose to use "collection based" multitenancy, i.e. each tenant has its own set of collection. For example for the Article entity, the collections are "{tenantName}_articles".

Oliver Gierke在对spring-data-mongodb进行多次租户使用例如:

Oliver Gierke kindly explained an implementation in Making spring-data-mongodb multi-tenant using for example :

@Document(collectionName = "#{tenantProvider.getTenantId()}_articles")

这在纸上非常好,但是似乎不适用于现实生活中的应用,因为我发现了两个问题,一个是主要问题:

This is very nice on paper, but does not seem applicable for real life applications as I found two issues, one being major:

问题1 (我可以接受):在应用程序启动时,Spring Boot使数据库为具有自定义索引(例如@Indexed属性)的实体建立索引.但是在启动时,没有当前租户",因此Spring Data会创建不相关的集合,例如"_articles".我们如何防止这种情况?

Issue 1 (I could live with that): at application startup Spring Boot makes the database build the indexes for entities that have custom indexes (such as @Indexed attributes). But at startup, there is no "current tenant" so Spring Data creates irrelevant collections such as "_articles". How can we prevent this?

问题2 (此处的主要问题):在运行时,创建并使用了多租户集合(例如"{tenantName} _articles"),并且没有自定义索引(除了"_id"上的默认MongoDB索引).我怀疑Spring在运行时会忽略索引,因为它认为它已经在启动时完成了工作.这是一个主要的性能问题.我们该如何解决?

Issue 2 (major probleme here): at runtime the multitenant collections such as "{tenantName}_articles" are created and used without the custom indexes (apart from the default MongoDB index on "_id"). I suspect Spring ignores indexes at runtime because it thinks it already did the job at startup. This is a major performance problem. How can we fix this?

谢谢您的时间.

推荐答案

找到了一种为给定租户重新创建索引的方法:

Found a way to recreate the indexes for a given tenant:

String tenantName = ...;

MongoMappingContext mappingContext = (MongoMappingContext) mongoTemplate.getConverter().getMappingContext();
MongoPersistentEntityIndexResolver resolver = new MongoPersistentEntityIndexResolver(mappingContext);

for (BasicMongoPersistentEntity entity : mappingContext.getPersistentEntities()) {
    if (entity.findAnnotation(Document.class) == null) {
        // Keep only collection roots
        continue;
    }

    String collectionName = entity.getCollection();
    if (!collectionName.startsWith(tenantName)) {
        // Keep only dynamic entities
        continue;
    }

    IndexOperations indexOperations = mongoTemplate.indexOps(collectionName);
    for (MongoPersistentEntityIndexResolver.IndexDefinitionHolder holder : resolver.resolveIndexForEntity(entity)) {
        indexOperations.ensureIndex(holder.getIndexDefinition());
    }
}

花一些时间来解决这个问题.希望这会有所帮助.欢迎改进.

Took me some time to figure this out. Hope this will help. Improvements welcome.

这篇关于Spring Data MongoDB基于集合的多租户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆