MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Modellazione di sottoraccolte in MongoDB Realm Sync

Il tuo codice ha un bell'aspetto e la tua direzione nella giusta direzione, quindi questa risposta contiene più spiegazioni e suggerimenti sulla modellazione rispetto al codice rigido.

Innanzitutto, gli oggetti Realm sono pigramente caricato il che significa che vengono caricati solo quando vengono utilizzati. Decine di migliaia di oggetti avranno un impatto minimo sulla memoria di un dispositivo. Supponiamo quindi di avere 10.000 utenti e di "caricarli tutti"

let myTenThousandUsers = realm.objects(UserClass.self)

mah, niente di grave. Tuttavia, in questo modo

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

(potrebbe) creare un problema - se ciò restituisce 10.000 utenti sono tutti caricati in memoria possibilmente sovraccaricare il dispositivo. Questa è una funzione Swift e la "conversione" dei dati pigri di Realms utilizzando Swift dovrebbe generalmente essere evitata (dipende dal caso d'uso)

L'osservazione di questo codice usando Swift .forEach

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

potrebbe causare problemi a seconda di ciò che viene fatto con quegli oggetti del progetto:usarli come tableView dataSource potrebbe essere un problema se ce ne sono molti.

La seconda cosa è la domanda sul limite di 16 Mb per documento. Per chiarezza un documento Atlas è questo

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

dove valore può essere uno qualsiasi dei tipi di dati BSON come altri documenti, array e array di documenti.

Nella tua struttura, var tasks = RealmSwift.List<Task>() dove Task è un oggetto incorporato . Sebbene gli oggetti concettualmente incorporati siano oggetti, credo che contino per un limite di un singolo documento perché sono incorporati (correggimi se sbaglio); all'aumentare del numero di essi, cresce la dimensione del documento allegato, tenendo presente che 16Mb di testo sono ENORMI di testo, quindi potrebbero/potrebbero equivalere a milioni di attività per progetto.

La soluzione semplice è non incorporarli e farli stare in piedi da soli.

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"
    }
}

Quindi ognuno può essere 16Mb, e un 'numero illimitato' può essere associato a un singolo progetto. Un vantaggio degli oggetti incorporati è un tipo di eliminazione a cascata in cui quando l'oggetto padre viene eliminato, lo sono anche gli oggetti figlio, ma con una relazione 1-molti dal progetto alle attività:eliminare un gruppo di attività appartenenti a un genitore è facile.

Oh, un altro caso per non utilizzare oggetti incorporati, specialmente per questo caso d'uso, è che non possono avere proprietà indicizzate. Indicizzazione può velocizzare notevolmente alcune query.