sql >> Base de Datos >  >> NoSQL >> MongoDB

Modelado de subcolecciones en MongoDB Realm Sync

Su código se ve muy bien y se dirige en la dirección correcta, por lo que esta respuesta es más una explicación y sugerencias sobre el modelado que el código duro.

Primero, los objetos Realm son lazily cargado lo que significa que solo se cargan cuando se usan. Decenas de miles de objetos tendrán muy poco impacto en la memoria de un dispositivo. Supongamos que tiene 10 000 usuarios y los 'carga todos'

let myTenThousandUsers = realm.objects(UserClass.self)

meh, no es gran cosa. Sin embargo, hacer esto

let someFilteredUsers = myTenThousandUsers.filter { $0.blah == "blah" }

creará (podría) crear un problema:si eso devuelve 10,000 usuarios todos están cargados en la memoria posiblemente abrumando el dispositivo. Esa es una función Swift y, en general, se debe evitar la "conversión" de datos perezosos de Realms usando Swift (depende del caso de uso)

La observación de este código usando Swift .forEach

realm.objects(Project.self).forEach { (project) in
   // Access fields     
}

podría causar problemas dependiendo de lo que se haga con esos objetos del proyecto; usarlos como fuente de datos de tableView podría ser problemático si hay muchos de ellos.

Lo segundo es la pregunta sobre el límite de 16 Mb por documento. Para mayor claridad, un documento Atlas es este

{
   field1: value1,
   field2: value2,
   field3: value3,
   ...
   fieldN: valueN
}

donde el valor puede ser cualquiera de los tipos de datos BSON, como otros documentos, matrices y matrices de documentos.

En su estructura, var tasks = RealmSwift.List<Task>() donde Tarea es un objeto incrustado . Si bien los objetos incrustados conceptualmente son objetos, creo que cuentan para el límite de un solo documento porque están incrustados (corríjame si me equivoco); a medida que crece el número de ellos, crece el tamaño del documento adjunto, teniendo en cuenta que 16 Mb de texto es ENORME, por lo que equivaldría a millones de tareas por proyecto.

La solución simple es no incrustarlos y hacer que se mantengan solos.

class Task: Object {
    @objc dynamic var _id: String = ObjectId.generate().stringValue
    @objc dynamic var _partition: String = "" 
    @objc dynamic var name: String = ""
    @objc dynamic var status: String = "Pending"
    override static func primaryKey() -> String? {
        return "_id"
    }
}

Entonces, cada uno puede tener 16 Mb y un 'número ilimitado' puede asociarse con un solo proyecto. Una ventaja de los objetos incrustados es un tipo de eliminación en cascada en la que cuando se elimina el objeto principal, los objetos secundarios también lo hacen, pero con una relación 1-muchos desde Proyecto a Tareas:eliminar un montón de tareas que pertenecen a un elemento principal es fácil.

Oh, otro caso para no usar objetos incrustados, especialmente para este caso de uso, es que no pueden tener propiedades indexadas. Indización puede acelerar considerablemente algunas consultas.