Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios MongoDB领域同步中的子集合建模_Ios_Swift_Mongodb_Realm_Mongodb Realm - Fatal编程技术网

Ios MongoDB领域同步中的子集合建模

Ios MongoDB领域同步中的子集合建模,ios,swift,mongodb,realm,mongodb-realm,Ios,Swift,Mongodb,Realm,Mongodb Realm,我对MongoDB和MongoDB领域同步都是新手。我一直在关注和,但我想了解更多,所以我调整了Atlas收集结构,如下所示 Projects > Tasks // i.e. tasks is a sub-collection in each project. // Read projects realm.objects(Project.self).forEach { (project) in // Access fields } // Create a

我对MongoDB和MongoDB领域同步都是新手。我一直在关注和,但我想了解更多,所以我调整了Atlas收集结构,如下所示

Projects > Tasks // i.e. tasks is a sub-collection in each project.
// Read projects
realm.objects(Project.self).forEach { (project) in
   // Access fields     
}
        
// Create a new project
try! realm.write {
    realm.add(project)
}
我不知道的是如何提出一个能够支持Atlas子集合的领域同步模式。 我想到的最好的方案是将
任务
建模为
项目
中的数组。但,我担心这可能会达到16MB(尽管很多!)的文档限制,用于有很多任务的项目

{
  "bsonType": "object",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "_partition": {
      "bsonType": "string"
    },
    "name": {
      "bsonType": "string"
    },
    "tasks": {
      "bsonType": "array",
      "items": {
          "bsonType": "object",
          "title": "Task",
          "properties": {
              "name": {
                "bsonType": "string"
              },
              "status": {
                "bsonType": "string"
              }
          }
      }
    }
  },
  "required": [
    "_id",
    "_partition",
    "name",
  ],
  "title": "Project"
}
期待着如何正确的模式子集合的方式

编辑

这是我的客户端领域模型

import Foundation
import RealmSwift

class Project: Object {
    @objc dynamic var _id: String = ObjectId.generate().stringValue
    @objc dynamic var _partition: String = "" // user.id
    @objc dynamic var name: String = ""
    var tasks = RealmSwift.List<Task>()
    override static func primaryKey() -> String? {
        return "_id"
    }
}

class Task: EmbeddedObject {
    @objc dynamic var name: String = ""
    @objc dynamic var status: String = "Pending"
}

您的代码看起来很棒,方向正确,因此,与硬代码相比,这个答案更多的是关于建模的解释和建议

首先,领域对象是动态的,这意味着它们只有在使用时才被加载。成千上万的对象对设备内存的影响很小。因此,假设您有10000个用户,并且“全部加载到”

let myThenThousandUsers = realm.objects(UserClass.self)
没什么大不了的。但是,

let someFilteredUsers = myTenThousandUsers.filter { $0.blah == "blah" }
将(可能)产生一个问题-如果返回10000个用户,他们都被加载到内存中,可能会使设备无法承受。这是一个Swift函数,通常应避免使用Swift“转换”惰性数据(取决于用例)

使用Swift.forEach观察此代码

realm.objects(Project.self).forEach { (project) in
   // Access fields     
}
可能会导致问题,具体取决于对这些项目对象所做的操作——如果有很多项目对象,将它们用作tableView数据源可能会有麻烦

第二件事是关于每个文档16Mb限制的问题。为了清楚起见,这是一份Atlas文件

{
   field1: value1,
   field2: value2,
   field3: value3,
   ...
   fieldN: valueN
}
其中,值可以是任何BSON数据类型,例如其他文档、数组和文档数组

在您的结构中,
var tasks=RealmSwift.List()。虽然概念上嵌入的对象是对象,但我相信它们会计入单个文档的限制,因为它们是嵌入的(如果我错了,请纠正我);随着它们数量的增长,随附文档的大小也在增长——请记住16Mb的文本是一个巨大的文本,因此每个项目将/可能相当于数百万个任务

简单的解决方案是不嵌入它们,而是让它们独立存在

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"
    }
}
然后每个都可以是16Mb,并且“无限数量”可以与单个项目关联。嵌入对象的一个优点是一种级联删除类型,当父对象被删除时,子对象也会被删除,但是从项目到任务之间有一个1-many关系——删除一组属于父对象的任务很容易


哦,不使用嵌入对象的另一种情况——特别是对于这个用例——是它们不能有索引属性。可以大大加快某些查询。

由于术语的原因,这个问题有点令人困惑,而不是您的做法,因为Realm和MongoDB Atlas之间存在一些重叠。领域集合是同质的数据集,有两种类型的集合:领域集合和列表集合。另一方面,阿特拉斯收藏可以是非同质的“任何东西”。。Atlas不能有子集合,而Realm可以。我想你问的是ObjectRealm中的List属性。同样,不清楚对象的形状与限制的关系;领域没有数组,那么这是什么类型的领域属性呢?如果它是一个领域对象中的列表属性,那么列表中的对象不是“在”主对象中-只是对它们的引用,因此影响最小。你有没有看到文件的最大大小是4Mb?通过使用GridFS(图像、视频等),您可以放大屏幕。如果我们了解您的编码平台,也许我们可以提供更多帮助。@Jay谢谢您提出了一些要点。两件事,首先限制是16MB(这是我的一个错误!)。关于子集合,我指的是Atlas嵌套文档(子集合是Firebase world中使用的一个术语!)。我认为Atlas嵌套文档是根据16MB文档限制计算的——因此我担心,将任务列表和项目中的任务建模为Atlas嵌套文档(以及客户端的领域列表)将耗尽该限制。那么,我如何在Atlas&Realm上以适当的方式将其建模为参考,而不是嵌套文档呢,但我还没有把领域的术语绕到我的头上:)你也应该把你的编码平台作为一个标签,这样任何答案都会更符合你所做的。首先,感谢你给出了这样一个有见地的答案。我不知道你最后提到的索引部分。我计划试验的另一件事是“与其他用户共享项目”功能。将任务作为顶级集合将有所帮助,因为我可以提供项目id作为任务的
\u分区
键,并让用户通过同步权限规则授予对该分区的访问权限。将其作为嵌入对象意味着它继承分区,而这是不可能的。