MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Modelando subcoleções no MongoDB Realm Sync


Seu código parece ótimo e está indo na direção certa, então esta resposta é mais explicação e sugestões sobre modelagem do que código rígido.

Primeiro, os objetos Realm são preguiçosamente carregado o que significa que eles só são carregados quando usados. Dezenas de milhares de objetos terão muito pouco impacto na memória de um dispositivo. Então, suponha que você tenha 10.000 usuários e os 'carregue todos'
let myTenThousandUsers = realm.objects(UserClass.self)

meh, não é grande coisa. No entanto, fazendo isso
let someFilteredUsers = myTenThousandUsers.filter { $0.blah == "blah" }

irá (poderia) criar um problema - se isso retornar 10.000 usuários eles estão todos carregados na memória possivelmente sobrecarregando o dispositivo. Essa é uma função Swift e dados preguiçosos de 'conversão' de Realms usando Swift geralmente devem ser evitados (dependente do caso de uso)

A observação deste código usando Swift .forEach
realm.objects(Project.self).forEach { (project) in
   // Access fields     
}

pode causar problemas dependendo do que está sendo feito com esses objetos de projeto - usá-los como um tableView dataSource pode ser um problema se houver muitos deles.

A segunda coisa é a questão do limite de 16Mb por documento. Para maior clareza, um documento Atlas é este
{
   field1: value1,
   field2: value2,
   field3: value3,
   ...
   fieldN: valueN
}

em que valor pode ser qualquer um dos tipos de dados BSON, como outros documentos, matrizes e matrizes de documentos.

Em sua estrutura, o var tasks = RealmSwift.List<Task>() onde Tarefa é um objeto incorporado . Embora os objetos conceitualmente incorporados sejam objetos, acredito que eles contam para um único limite de documento porque estão incorporados (corrija-me se estiver errado); à medida que o número deles cresce, o tamanho do documento anexo cresce - tendo em mente que 16Mb de texto é um ENORME de texto, o que equivaleria a milhões de tarefas por projeto.

A solução simples é não incorporá-los e deixá-los em pé por conta própria.
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"
    }
}

Então cada um pode ter 16Mb, e um 'número ilimitado' pode ser associado a um único projeto. Uma vantagem dos objetos incorporados é um tipo de exclusão em cascata onde, quando o objeto pai é excluído, os objetos filho também, mas com um relacionamento 1-muitos de Projeto para Tarefas - é fácil excluir um monte de tarefas pertencentes a um pai.

Oh - outro caso para não usar objetos incorporados - especialmente para este caso de uso - é que eles não podem ter propriedades indexadas. Indexação pode acelerar bastante algumas consultas.