【问题标题】:Can the MongoDB Realm Swift API still just insert a struct into an Atlas collection, like in Stitch?MongoDB Realm Swift API 仍然可以像在 Stitch 中那样将结构插入 Atlas 集合吗?
【发布时间】:2021-08-22 01:28:19
【问题描述】:

我有一个可编码的 Swift 结构层次结构,我需要将其存储在云中的 MongoDB (Atlas) 中。我确实不需要在本地保存这些结构,并且这个应用程序一旦存储就不需要访问这些数据。 (还有其他应用程序访问它,但这超出了这个问题的范围。)

MongoDB 曾经提供一个名为 Stitch 的解决方案,它确实允许我这样做:我的 iOS 应用程序有一个 codable Swift 结构,iOS 应用程序连接到 MongoDB 的 Atlas 云上的 Stitch 应用程序,我能够插入将结构体放入数据库中的集合中。

使用 Stitch,我可以这样做:

let itemsCollection = mongoServiceClient.db(“myDatabase”).collection(“myCollection”,
    withCollectionType: MyStruct.self)
itemsCollection.insertOne(myStruct) 

现在 Stitch 显然已弃用并被 Realm 取代,Realm 是 MongoDB 收购并与其 Atlas 云集成的以前的第三方本地持久层。

Realm 与 Stitch 不向后兼容,并且它似乎不再能够将 Swift 结构映射到 MongoDB 后端:它现在可以同步 Realm 对象,即 Realm 定义的抽象基类的 ObjC 桥接子类.将我的应用程序在多个地方使用的几十个结构转换成这样的类太复杂了,特别是因为我这样做的唯一目的是为了将它们上传到后端,因为我不需要任何(毫无疑问非常好) Realm 的核心功能。

(顺便说一句,我发现从结构体到对象的迁移,尤其是在 Objective-C 基础的情况下,非常令人费解,因为它非常违背流程:很明显 Swift 和值类型是 Apple 的未来平台...)

我的问题:有没有一种我可能错过的方法来连接到 Atlas 上的 Realm 应用程序,并将定义为 Swift 结构的文档插入到 Atlas DB 中的集合中?

或者是否有一种相当简单的方法可以将 JSON 转换为 Realm 对象?根据我的阅读,我仍然需要为对象定义一个模式,并且由于我的源结构包含多个嵌入式结构,因此需要为每个结构创建 Object 子类,这是我真正需要避免的。基本上,我围绕 MongoDB 和 Stitch 设计了我的应用程序的这个功能,我还没有准备好突然适应 Realm 的限制而没有附加价值。

最后,失败了,有没有办法将我的结构编码为一些官方 MongoDB API(例如 Realm)可以用于插入的格式?

我已经可以将我的结构编码为 JSON,但这似乎还不够。我看过有关MongoDB Realm Remote Access 的文档,但除了连接到数据库之外,它并没有说明我的用例。

我收到的错误消息表明我需要创建一个Document(又名Dictionary<String, Optional<AnyBSON>>),其中AnyBSON 是一个定义BSON 值类型的枚举。我还没有找到任何关于将任何内容转换为该格式的文档:是否有用于该格式的 API,或者我是否需要将我的结构或 JSON 分解为 AnyBSON 值的层次结构?

【问题讨论】:

  • 这个问题很难理解。你问的是 MongoDB 还是 Realm?阿特拉斯是什么?它的一部分还读作“我想使用 Realm,但我不想使用 Realm,因为我不喜欢它的 API”,这……令人困惑,我不确定你在寻找什么
  • 缝合?阿特拉斯?它们是什么,它们与在 Swift 中开发什么有什么关系?
  • @Alexander 问题显然是针对那些了解 MongoDB 和 Realm 的人。如果您仔细阅读,我看不出我的问题有多么令人困惑:这是最后一段。
  • 我认为这可能会限制您获得的读者/回答者的数量,因为只知道 MongoDB 或只知道 Realm 的人将无法提供帮助,因为他们不了解另一个。我认为,如果您以更详细的方式表达您的问题,从而减少潜在回答者需要知道的背景知识,您将获得更好的成功。
  • 我很感激,但这是关于 Swift SDK for Realm 的一个非常具体的问题。我知道组合的用户不多,但就是这样。

标签: swift mongodb realm mongodb-stitch


【解决方案1】:

我将在此答案的开头声明这不是一个具体的答案,而是有关如何完成问题中提出的问题的更多指导。

首先,让我重新陈述问题

将数据插入MongoDB Realm而不存储的过程是什么 它在本地或使用 Realm 对象;改用 Classes、Structs(或其他东西)。

为了说明,我们在 MongoDB Realm (Atlas) 中存储了一些任务,而本地没有存储任何内容。在这里我将创建一个包含任务信息的 Document 并插入它。

我们首先需要定义数据将存储在哪里以及将其存储在哪个集合中:

let app = Your App
let client = app.currentUser!.mongoClient("mongodb-atlas")
let database = client.database(named: "task-database")
let collection = database.collection(withName: "TaskClass")

然后我们将创建一些 BSON 来存储文本数据

let _id = AnyBSON(ObjectId.generate())
let taskName = AnyBSON(stringLiteral: "Inserted Task")
let status = AnyBSON(stringLiteral: "Open")
let partition = AnyBSON(stringLiteral: Constants.REALM_PARTITION_VALUE)

然后,对于每个 BSON,给每个 BSON 一个键:值对(字典)

let idDict = ("_id", _id)
let taskDict = ("name", taskName )
let statusDict = ("status", status)
let partitionDict = ("_partitionKey", partition)'

最后我们将创建一个文档并将其写入 MongoDB 领域

let myTaskDoc = Document(dictionaryLiteral: idDict, taskDict, statusDict, partitionDict)

collection.insertOne(myTaskDoc, { result in
    print(result)
})

以上代码回答了问题

MongoDB Realm Swift API 是否仍然只是将一个结构插入到一个 Atlas 集合,就像在 Stitch 中一样?

是的!事实上,我完全没有使用 Struct 就做到了。请记住,上面的代码实际上是为了简单起见——显然利用Structs 或Classes 将为您的数据提供更多的灵活性和封装。这将通过制作或更新现有的类或结构来完成,因此当要写入数据时,可以使用一个函数来设置 AnyBSON 格式的属性并返回一个文档。

class TaskClass {
   var name = ""

   func toBson() -> Document {
       let taskName = AnyBSON(stringLiteral: self.name)
       let taskDict = ("name", taskName )
       let myTaskDoc = Document(dictionaryLiteral: taskDict) //abbreviated
       return myTaskDoc
}

然后使用

let doc = myTask.toBson()
collection.insertOne(doc, { result in
   print(result)
})

这可以很容易地扩展为使用 Codable 和 JSONEncoder() 将 JSON 数据直接存储在您的结构中,然后将 BSON 数据发送到服务器

【讨论】:

  • 谢谢;这很有趣,我可能会在某些情况下使用它。但是,我的问题是有一个带有嵌入式子结构的现有结构,我可以将其添加到 JSON 中,并且我可以很容易地通过 Stitch 将其插入到 MongoDB 中。您描述的内容很有用,因为现在我知道如何为 Realm 构建 BSON 数据;但是,这仍然涉及手动重建复杂的结构。我最终可能会 (1) 在与 Atlas 兼容的情况下使用 Stitch,(2) 找到 JSON 到 BSON 的转换机制,或者 (3) 尝试将旧的 Stitch 功能集成回 Realm API。
  • 实际上,我正在考虑一个涉及result builders 的解决方案,以根据您的回答构造一个 BSON 对象。 (我只是尝试使用SwiftBSON(尽管它在iOS上没有正式支持),但它的Document类型与Realm使用的同名类型不一样,而且似乎并不容易在它们之间进行转换的方式......所以使用它意味着完全绕过 Realm。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 2022-06-11
  • 2020-11-06
  • 2012-09-19
  • 2019-07-15
  • 1970-01-01
相关资源
最近更新 更多