sql >> Database >  >> NoSQL >> MongoDB

Modellering van subcollecties in MongoDB Realm Sync

Je code ziet er geweldig uit en je gaat de goede kant op, dus dit antwoord is meer uitleg en suggesties voor modellering dan harde code.

Ten eerste zijn Realm-objecten lui geladen wat betekent dat ze alleen worden geladen wanneer ze worden gebruikt. Tienduizenden objecten hebben weinig invloed op het geheugen van een apparaat. Dus stel dat je 10.000 gebruikers hebt en je 'laadt ze allemaal in'

let myTenThousandUsers = realm.objects(UserClass.self)

mwah, niet erg. Als u dit echter doet

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

zal een probleem (kunnen) veroorzaken - als dat 10.000 gebruikers oplevert ze worden allemaal in het geheugen geladen mogelijk overweldigend het apparaat. Dat is een Swift-functie en het 'converteren' van Realms luie gegevens met Swift moeten over het algemeen worden vermeden (afhankelijk van het gebruik)

De observatie van deze code met Swift .forEach

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

kan problemen veroorzaken, afhankelijk van wat er met die projectobjecten wordt gedaan - het gebruik ervan als een tabelView dataSource kan problemen opleveren als er veel zijn.

Ten tweede is er de vraag naar de limiet van 16 Mb per document. Voor de duidelijkheid is dit een Atlas-document

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

waarbij waarde elk van de BSON-gegevenstypen kan zijn, zoals andere documenten, arrays en arrays van documenten.

In uw structuur, de var tasks = RealmSwift.List<Task>() waarbij Taak een embedded object is . Hoewel conceptueel ingebedde objecten objecten zijn, geloof ik dat ze meetellen voor een enkele documentlimiet omdat ze zijn ingesloten (corrigeer me als ik het mis heb); naarmate het aantal groeit, groeit de omvang van het bijgevoegde document - in gedachten houdend dat 16 MB tekst ENORME tekst is, dus dat zou/kon gelijk staan ​​aan miljoenen taken per project.

De eenvoudige oplossing is om ze niet in te bedden en ze op zichzelf te laten staan.

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

Dan kan elk 16Mb groot zijn en kan een 'onbeperkt aantal' aan een enkel project worden gekoppeld. Een voordeel van ingesloten objecten is een soort trapsgewijs verwijderen waarbij wanneer het bovenliggende object wordt verwijderd, de onderliggende objecten dat ook zijn, maar met een 1-many-relatie van Project tot Taken - het verwijderen van een aantal taken van een bovenliggend object is eenvoudig.

Oh - een ander geval voor het niet gebruiken van ingesloten objecten - vooral voor dit gebruik - is dat ze geen geïndexeerde eigenschappen kunnen hebben. Indexeren kan sommige zoekopdrachten aanzienlijk versnellen.




  1. Query's uitvoeren op geneste objectarrays

  2. Apache-Nifi:MongoDB-verzamelingen verwijderen

  3. int naar zwevende conversie in Mongo find

  4. COD en CML gebruiken om applicaties te bouwen die voorraadgegevens voorspellen