sql >> Databasteknik >  >> NoSQL >> MongoDB

Modellera undersamlingar i MongoDB Realm Sync

Din kod ser bra ut och du är på väg åt rätt håll, så det här svaret är mer förklaringar och förslag på modellering än hårdkod.

För det första är Realm-objekt lata laddas vilket innebär att de bara laddas när de används. Tiotusentals objekt kommer att ha mycket liten inverkan på enhetens minne. Så anta att du har 10 000 användare och du "laddar in dem alla"

let myTenThousandUsers = realm.objects(UserClass.self)

meh, ingen stor grej. Men gör detta

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

kommer (kan) skapa ett problem - om det returnerar 10 000 användare läggs de alla in i minnet eventuellt överväldigande enheten. Det är en Swift-funktion och att "konvertera" Realms lata data med Swift bör i allmänhet undvikas (användningsfallsberoende)

Observationen av denna kod med Swift .forEach

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

kan orsaka problem beroende på vad som görs med dessa projektobjekt - att använda dem som en tableView-datakälla kan vara problem om det finns många av dem.

För det andra är frågan om gränsen på 16Mb per dokument. För tydlighetens skull är ett Atlas-dokument detta

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

där värdet kan vara vilken som helst av BSON-datatyperna som andra dokument, arrayer och arrayer av dokument.

I din struktur är var tasks = RealmSwift.List<Task>() där Task är ett inbäddat objekt . Även om begreppsmässigt inbäddade objekt är objekt, tror jag att de räknas mot en enda dokumentgräns eftersom de är inbäddade (rätta mig om jag har fel); när antalet av dem växer, ökar storleken på det bifogade dokumentet - med tanke på att 16 Mb text är ENORMT text så det skulle/kan motsvara miljontals uppgifter per projekt.

Den enkla lösningen är att inte bädda in dem och låta dem stå på egen hand.

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

Då kan var och en vara på 16 Mb, och ett "obegränsat antal" kan kopplas till ett enda projekt. En fördel med inbäddade objekt är en typ av kaskadborttagning där när det överordnade objektet raderas, så är de underordnade objekten det också, men med en 1-många relation från projekt till uppgifter - att ta bort ett gäng uppgifter som tillhör en förälder är enkelt.

Åh - ett annat fall för att inte använda inbäddade objekt - speciellt för detta användningsfall - är att de inte kan ha indexerade egenskaper. Indexering kan avsevärt påskynda vissa frågor.




  1. flera dokumenttransaktioner fungerar inte i c# med mongodb 4.08 community-server

  2. gränser för antalet samlingar i databaser

  3. Kubernetes statefulset med NFS-beständig volym

  4. Använd fall för Redis poäng och rankningsfunktioner för set