You can implement multi-tenancy with MongoDB Vector Search so that a single instance of an application serves multiple tenants. This page describes design recommendations that apply specifically to MongoDB Vector Search. These recommendations differ from our multi-tenancy recommendations for Atlas.
建议
在为MongoDB Vector Search 设计多租户架构时,请参阅以下建议。
重要
本指导假设您可以在单个VPC中并置租户。否则,您必须为每个租户维护单独的项目,我们不建议对MongoDB Vector Search 这样做。
一个集合适用于所有租户
我们建议将所有租户数据存储在单个集合、单个数据库和集群中。您可以通过在每个文档中包含 tenant_id 字段来区分不同租户。此字段可以是租户的任何唯一标识符,例如 UUID 或租户名称。您可以在 MongoDB 向量搜索索引和查询中使用此字段作为 预过滤器。
这种集中式方法具有以下优点:
易于建模和扩展。
简化维护操作。
通过
tenant_id预过滤以实现高效的查询路由。注意
此过滤器的 ACID 一致性保证确保查询仅返回与此过滤器匹配的租户的数据。
每个租户一个集合或每个租户一个数据库
由于以下原因,我们不建议将每个租户存储在单独的集合或数据库中:
性能影响:此方法可能会导致变更流负载发生变化,具体取决于集合数量,这可能会对性能和监控功能产生负面影响。
无需额外隔离:Atlas中的隔离性ACID 一致性保证应用于数据库级别。在同一数据库中使用单独的集合不会提供额外的数据隔离性优势。使用单独的数据库会带来操作复杂性,对于大多数使用案例来说,没有任何有意义的安全优势。
相反,对所有租户使用一个集合。有关如何从每个租户一个集合模型迁移到单个集合模型的示例,请参阅从每个租户一个集合模型迁移。
Considerations
请考虑以下策略,使用推荐的方法缓解潜在的性能问题。
租户大小差异
如果您有许多租户,但每个租户的文档相对较少,或者由于数据分布不均衡(一些大租户和许多小租户)而遇到性能问题,请考虑以下策略。
对许多小型租户使用平面索引
如果您有许多租户(最多 1 万),并且每个租户的文档相对较少(每个租户少于 10,000 个文档),请使用 flat 索引而不是默认的 Hierarchical Navigable Small Worlds 索引。要创建平面索引,请在索引定义中将 indexingMethod 字段设置为 flat。
当每个租户拥有少量文档时,筛选到特定租户的查询已经过全面搜索。在这些情况下,Hierarchical Navigable Small Worlds 图表无法提供任何优势,但会增加内存和维护开销。平面索引可消除这种不必要的开销。
平面索引可为多租户工作负载提供以下优势:
针对选择性过滤器进行了优化:对于每个租户拥有少量文档的高度选择性查询,穷举扫描已经是最快路径。平面索引直接支持这一点,从而改善延迟和召回。
可预测的性能:无论针对哪个租户,查询延迟都保持在一个狭窄的范围内,从而消除了租户之间的嘈杂邻居影响。
资源效率:扁平索引消除了与构建“分层可导航小世界”图表相关的内存和维护开销。
示例,以下索引定义创建带有 tenant_id 过滤器字段的平面索引。如果您希望 MongoDB 向量搜索使用 Voyage AI 模型自动生成嵌入,请选择 autoEmbed 类型;如果您已有嵌入,请选择 vector 类型:
{ "fields": [ { "type": "autoEmbed", "modality": "text", "path": "<fieldToIndex>", "model": "<embeddingModel>", "indexingMethod": "flat" }, { "type": "filter", "path": "tenant_id" } ] }
{ "fields": [ { "type": "vector", "path": "<fieldToIndex>", "numDimensions": <numberOfDimensions>, "similarity": "euclidean | cosine | dotProduct", "indexingMethod": "flat" }, { "type": "filter", "path": "tenant_id" } ] }
对较大租户的视图使用 HNSW 索引
对于每个拥有超过 10、000 个文档的较大租户,请在 Hierarchical Navigable Small Worlds 上使用索引 MongoDB Views 将大租户与小租户分开:
大型租户(前 1%):
为每个大型租户创建一个视图。
为每个视图创建一个Hierarchical Navigable Small Worlds索引。
维护大型租户的记录,在查询时进行检查,以便相应地路由查询。
小型租户(剩余租户):
为所有小型租户创建单一视图。
Build a single flat index for this view.
使用
tenant_id字段作为预过滤器来相应地路由查询。
例子
The following example demonstrates how to create views for large and small tenants by using mongosh:
记录您的大型租户及其相应的 tenant_id 值,然后为每个租户创建一个视图:
db.createView( "<viewName>", "<collectionName>", [ { "$match": { "tenant_id": "<largeTenantId>" } } ] )
为小型租户创建视图,过滤掉大型租户:
db.createView( "<viewName>", "<collectionName>", [ { "$match": { "tenant_id": { "$nin": [ "<largeTenantId1>", "<largeTenantId2>", ... ] } } } ] )
创建视图后,为每个视图创建索引。请验证以下内容:
在为索引指定集合名称时,请使用视图名称而非原始集合名称。
对于大型租户视图,请创建Hierarchical Navigable Small Worlds索引(默认)。
For the small tenant view, create an index with the flat indexing method and include the
tenant_idfield as a pre-filter.
有关创建索引的说明,请参阅创建索引页面。
许多大型租户
If you have many tenants that each have a large number of documents, consider using a partition-based system by distributing data across shards.
从“每个租户一个集合”模型迁移
要从每个租户一个集合的模型迁移到单个集合的模型,请处理每个租户的集合,并将文档插入到一个新的集合中。