Puedes implementar la Multiarrendamiento con MongoDB Vector Search para que una única instancia de una aplicación sirva para múltiples inquilinos. Esta página describe las recomendaciones de diseño que se aplican específicamente a MongoDB Vector Search. Estas recomendaciones difieren de nuestro Recomendaciones de múltiples tenencias para Atlas.
Recomendaciones
Consulta las siguientes recomendaciones al diseñar una arquitectura multiinquilino para MongoDB Vector Search.
Importante
Esta orientación supone que se pueden ubicar los inquilinos en una sola VPC. De lo contrario, deberá mantener proyectos separados para cada inquilino, lo cual no recomendamos para MongoDB Vector Search.
Una colección para todos los inquilinos
Recomendamos almacenar todos los datos de los inquilinos en una sola colección, así como en una única base de datos y clúster. Puede distinguir entre inquilinos incluyendo un tenant_id campo dentro de cada documento. Este campo puede ser cualquier identificador único para el arrendatario, como un UUID o un nombre de arrendatario. Puede utilizar este campo como un pre-filtro en sus índices y queries de MongoDB Vector Search.
Este enfoque centralizado ofrece los siguientes beneficios:
Fácil de modelar y escalar.
Simplifica las operaciones de mantenimiento.
Enrutamiento eficiente de query mediante prefiltrado por
tenant_id.Nota
Se le garantiza que no atenderá a inquilinos que no coincidan con este filtro.
Una colección por inquilino u una base de datos por inquilino
No recomendamos almacenar cada inquilino en una colección o base de datos diferente por las siguientes razones:
Impacto en el rendimiento: Este enfoque puede generar diferentes flujo de cambios cargas dependiendo del número de colecciones, lo que podría afectar negativamente el rendimiento y las capacidades de supervisión.
Sin aislamiento adicional: Las garantías de aislamiento de datos en Atlas se aplican a nivel de base de datos. El uso de colecciones separadas dentro de la misma base de datos no ofrece ningún beneficio adicional de aislamiento de datos. El uso de bases de datos independientes introduce complejidad operativa sin ventajas significativas de seguridad en la mayoría de los casos de uso.
En su lugar, utilice una sola colección para todos los inquilinos. Para ver un ejemplo de cómo migrar de un modelo de colección por inquilino a uno de colección única, consulte Migración desde un modelo de colección por inquilino.
Considerations
Considera las siguientes estrategias para mitigar posibles problemas de rendimiento con el enfoque recomendado.
Discrepancias en el tamaño del inquilino
Si experimentas problemas de rendimiento por la distribución desigual de datos (algunos inquilinos grandes y muchos inquilinos pequeños), utiliza las vistas de MongoDB para separar los inquilinos grandes de los inquilinos más pequeños:
Grandes inquilinos (Top 1%):
Crea una vista para cada inquilino grande.
Crea un índice para cada vista.
Mantén un registro de grandes inquilinos que verifiques en tiempo de query para dirigir las queries en consecuencia.
Pequeños inquilinos (inquilinos restantes):
Crear una vista única para todos los pequeños inquilinos.
Crear un solo índice para esta vista.
Utiliza el campo
tenant_idcomo pre-filtro para enrutar las consultas en consecuencia.
Ejemplo
El siguiente ejemplo muestra cómo crear vistas para grandes y pequeños inquilinos usando mongosh:
Mantenga un registro de sus inquilinos grandes y sus valores tenant_id correspondientes y luego cree una vista para cada uno de estos inquilinos:
db.createView( "<viewName>", "<collectionName>", [ { "$match": { "tenant_id": "<largeTenantId>" } } ] )
Crear una vista para los pequeños inquilinos, excluyendo a los grandes inquilinos:
db.createView( "<viewName>", "<collectionName>", [ { "$match": { "tenant_id": { "$nin": [ "<largeTenantId1>", "<largeTenantId2>", ... ] } } } ] )
Después de crear las vistas, crea los índices para cada vista. Verifica lo siguiente:
Al especificar el nombre de la colección para el índice, utiliza el nombre de la vista en lugar del nombre original de la colección.
Asegúrese de que su índice en la vista de arrendatario pequeño incluya el campo
tenant_idcomo filtro previo.
Consulte la página Crear índices para obtener instrucciones sobre cómo crear índices.
Muchos usuarios grandes
Si tienes muchos tenants (arrendatarios) que cada uno tiene un gran número de vectores, considera usar un sistema basado en particiones distribuyendo los datos entre los fragmentos.
Puedes usar el campo tenant_id como llave de partición para distribuir los datos a través de rangos específicos basados en el ID de arrendatario. Para más información, consulta Particionado clasificado por rango.
Migración desde un modelo de colección por inquilino
Para migrar de un modelo de colección por inquilino a un modelo de colección única, procesa cada colección de inquilinos e inserta los documentos en una nueva colección.
Por ejemplo, el siguiente script utiliza el driver de Node.js para migrar los datos de un modelo de colección por arrendatario a un modelo de colección única. El script también incluye un campo tenant_id para cada documento basado en el nombre de la colección de origen.
import { MongoClient } from 'mongodb'; const uri = "<connectionString>"; const sourceDbName = "<sourceDatabaseName>"; const targetDbName = "<targetDatabaseName>"; const targetCollectionName = "<targetCollectionName>"; async function migrateCollections() { const client = new MongoClient(uri); try { await client.connect(); const sourceDb = client.db(sourceDbName); const targetDb = client.db(targetDbName); const targetCollection = targetDb.collection(targetCollectionName); const collections = await sourceDb.listCollections().toArray(); console.log(`Found ${collections.length} collections.`); const BATCH_SIZE = 1000; // Define a suitable batch size based on your requirements let totalProcessed = 0; for (const collectionInfo of collections) { const collection = sourceDb.collection(collectionInfo.name); let documentsProcessed = 0; let batch = []; const tenantId = collectionInfo.name; // Uses the collection name as the tenant_id const cursor = collection.find({}); for await (const doc of cursor) { doc.tenant_id = tenantId; // Adds a tenant_id field to each document batch.push(doc); if (batch.length >= BATCH_SIZE) { await targetCollection.insertMany(batch); totalProcessed += batch.length; documentsProcessed += batch.length; console.log(`Processed ${documentsProcessed} documents from ${collectionInfo.name}. Total processed: ${totalProcessed}`); batch = []; } } if (batch.length > 0) { await targetCollection.insertMany(batch); totalProcessed += batch.length; documentsProcessed += batch.length; console.log(`Processed ${documentsProcessed} documents from ${collectionInfo.name}. Total processed: ${totalProcessed}`); } } console.log(`Migration completed. Total documents processed: ${totalProcessed}`); } catch (err) { console.error('An error occurred:', err); } finally { await client.close(); } } await migrateCollections().catch(console.error);