简体   繁体   English

MongoDB Realm Swift API 仍然可以像在 Atlas 集合中插入一个结构吗?

[英]Can the MongoDB Realm Swift API still just insert a struct into an Atlas collection, like in Stitch?

I have a hierarchy of codable Swift structs that I need to store in MongoDB in the cloud (Atlas).我有一个可编码 Swift 结构的层次结构,我需要将其存储在云中的 MongoDB 中(Atlas)。 I do not need to persist these structs locally, and this app won't need to access this data once it's stored.不需要在本地持久化这些结构,而且这个应用程序一旦存储就不需要访问这些数据。 (There are other apps accessing it, but that's out of the scope of this question.) (还有其他应用程序访问它,但这不在此问题的 scope 范围内。)

MongoDB used to provide a solution called Stitch that did allow me to do just that: my iOS app had a codable Swift struct, the iOS app connected to a Stitch app on MongoDB's Atlas cloud, and I was able to insert the struct into a collection in the DB. MongoDB used to provide a solution called Stitch that did allow me to do just that: my iOS app had a codable Swift struct, the iOS app connected to a Stitch app on MongoDB's Atlas cloud, and I was able to insert the struct into a collection在数据库中。

With Stitch, I was able to just do it like this:使用 Stitch,我可以这样做:

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

Now Stitch is apparently deprecated and replaced by Realm, a formerly-third-party local persistency layer that MongoDB acquired and integrated with their Atlas cloud.现在 Stitch 显然已被弃用并被 Realm 取代,这是 MongoDB 收购并与他们的 Atlas 云集成的以前的第三方本地持久层。

Realm isn't backwards-compatible with Stitch, and it no longer seems to be able to map Swift structs to a MongoDB backend: it can now sync Realm objects, ie ObjC-bridged subclasses of an abstract base class that Realm defines. Realm isn't backwards-compatible with Stitch, and it no longer seems to be able to map Swift structs to a MongoDB backend: it can now sync Realm objects, ie ObjC-bridged subclasses of an abstract base class that Realm defines. Converting dozens of structs that my app uses in multiple places into such classes would be way too involved, especially since I would only do that for the sole purpose of uploading them to a backend as I do not need any of the (no doubt excellent) core functionalities of Realm.将我的应用程序在多个地方使用的几十个结构转换成这样的类太复杂了,特别是因为我这样做的唯一目的是为了将它们上传到后端,因为我不需要任何(毫无疑问非常好) Realm 的核心功能。

(By the way, I find the migration from structs to objects, especially with an Objective-C foundation, quite baffling, as it goes very much against the flow: it's quite clear that Swift and value types are the future for Apple's platforms...) (顺便说一句,我发现从结构到对象的迁移,尤其是在 Objective-C 基础上,非常令人费解,因为它非常不符合流程:很明显 Swift 和值类型是 Apple 平台的未来......)

My question : is there a way I may have missed to just connect to a Realm app on Atlas, and insert documents defined as Swift structs into a collection in an Atlas DB?我的问题:有没有一种方法我可能错过了连接到 Atlas 上的 Realm 应用程序,并将定义为 Swift 结构的文档插入到 Atlas DB 中的集合中?

Or is there a reasonably-easy way to convert JSON into a Realm object?或者是否有一种相当简单的方法可以将 JSON 转换为 Realm object? From what I read, I'd still need to define a schema for the object, and since my source struct contains several embedded structs, it would require creating Object subclasses for each, which is something I'd really need to avoid.根据我的阅读,我仍然需要为 object 定义一个模式,并且由于我的源结构包含多个嵌入式结构,因此需要为每个结构创建Object子类,这是我真正需要避免的。 Basically, I designed this functionality of my app around MongoDB and Stitch, and I'm not ready to suddenly accommodate the limitations of Realm for no added value.基本上,我围绕 MongoDB 和 Stitch 设计了我的应用程序的这个功能,我还没有准备好突然适应 Realm 的限制而没有附加价值。

Finally, failing all that, is there a way to encode my structs into a format that some official MongoDB API (eg Realm) can use for inserting?最后,失败了,有没有办法将我的结构编码为一些官方 MongoDB API(例如 Realm)可以用于插入的格式?

I can already encode my struct into JSON, but that doesn't seem to be enough.我已经可以将我的结构编码为 JSON,但这似乎还不够。 I have seen the doc about MongoDB Realm Remote Access , but it doesn't say anything about my use case beyond connecting to a DB.我看过有关MongoDB Realm Remote Access的文档,但除了连接到数据库之外,它没有说明我的用例。

Error messages I get suggest that I would need to create a Document (aka Dictionary<String, Optional<AnyBSON>> ), where AnyBSON is an enum that defines the type of the BSON value.我收到的错误消息表明我需要创建一个Document (又名Dictionary<String, Optional<AnyBSON>> ),其中AnyBSON是一个定义 BSON 值类型的枚举。 I haven't found any documentation about converting anything into that format: is there an API for that, or do I need to break down my struct or JSON into a hierarchy of AnyBSON values?我还没有找到任何关于将任何内容转换为该格式的文档:是否有 API ,或者我需要将我的结构或 JSON 分解为AnyBSON值的层次结构?

I'll preface this answer by stating it's not a specific answer but more guidance on how to accomplish what's asked in the question.我将通过说明这不是一个具体的答案,而是关于如何完成问题中提出的问题的更多指导来作为这个答案的序言。

First, let me re-state the question首先,让我重新陈述问题

What is the process to insert data into MongoDB Realm without storing it locally or using Realm objects;将数据插入 MongoDB Realm 而不将其存储在本地或使用 Realm 对象的过程是什么; use Classes, Structs (or something else) instead.改用类、结构(或其他东西)。

To illustrate, we have some tasks stored in MongoDB Realm (Atlas) with nothing stored locally.为了说明,我们在 MongoDB Realm (Atlas) 中存储了一些任务,而本地没有存储任何内容。 Here I will create a Document that contains task information and insert it.在这里,我将创建一个包含任务信息的文档并将其插入。

We first need to define where the data will be stored and what collection to store it in:我们首先需要定义数据将存储在哪里以及将其存储在哪个集合中:

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

then we'll create some BSON's to store the textual data in然后我们将创建一些 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)

then, for each BSON, give each a key: value pair (Dictionary)然后,对于每个 BSON,给每个 BSON 一个键:值对(字典)

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

finally we'll create and write a Document to MongoDB Realm最后我们将创建一个文档并将其写入 MongoDB Realm

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

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

The above code answers the question上面的代码回答了这个问题

Can the MongoDB Realm Swift API still just insert a struct into an Atlas collection, like in Stitch? MongoDB Realm Swift API 仍然可以像在 Atlas 集合中插入一个结构吗?

Yes.是的。 In fact I did it without using a Struct at all.事实上,我完全没有使用 Struct 就做到了。 Keeping in mind the above code is really for simplicity - obviously leveraging Structs or Classes will provide a lot more flexibility and encapsulation of your data.请记住,上面的代码实际上是为了简单起见——显然,利用StructsClasses将为您的数据提供更多的灵活性和封装。 This would be accomplished by crafting or updating an existing class or struct so when data is to be written utilize a function to set up the properties in AnyBSON format and return a Document.这将通过制作或更新现有的 class 或结构来完成,因此当要写入数据时,请使用 function 以 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
}

then to use然后使用

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

This could easily be expanded on using Codable and JSONEncoder() to directly store JSON data in your structs, and then send BSON data to the server这可以很容易地扩展为使用 Codable 和 JSONEncoder() 直接将 JSON 数据存储在您的结构中,然后将 BSON 数据发送到服务器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM