使用 Spring Data MongoDB 进行基于集合的多租户

2023-12-13

我们的 Spring Boot 1.3.3 应用程序使用 Spring Data MongoDB 1.8.4 将数据保存在 MongoDB (2.6 ou 3.2) 上。

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

Oliver Gierke 善意地解释了一个实现使 spring-data-mongodb 成为多租户例如使用:

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

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

Issue 1(我可以接受这一点):在应用程序启动时,Spring Boot 使数据库为具有自定义索引(例如 @Indexed 属性)的实体构建索引。但在启动时,没有“当前租户”,因此 Spring Data 创建了不相关的集合,例如“_articles”。我们怎样才能防止这种情况发生呢?

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

感谢您的时间。


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

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());
    }
}

我花了一些时间才弄清楚这一点。希望这会有所帮助。欢迎改进。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Spring Data MongoDB 进行基于集合的多租户 的相关文章

随机推荐