Realm Swift - Get all objects of a collecting matching part of the partition key

Hi,

I’m developing an iOS app using Swift and Realm Sync.
Each document stored in Atlas have the following partition key (string):

owner=<id_of_the_owner>,category=<id_of_the_category>

So far I only needed to access the documents of one category at a time. To do so, I open a Realm like this:

try! Realm(configuration: user!.configuration(partitionValue: “owner=<id_of_the_owner>,category=<id_of_the_category>”))

But now I would like to access all the documents of an owner, thus matching owner=<id_of_the_owner>.

I know I can do it with an Atlas Search Index but is there a way to do it directly in my app? For example, can I use regular expression in the partition key to do something like this:

owner=<id_of_the_owner>,category=(.*)

Thanks for your help!

1 Like

The partition key is the ‘name’ of a Realm - both on the server and locally as well. If you look at the actual Realm filenames, they are the specific name of the partition

Partition Values

Each unique partition value, or value of a partition key, maps to a different realm. Documents that share the same partition value belong to the same realm. All documents in a realm share the same read and write permissions.

As far as the client SDK goes, no that can’t directly be done.

So if your object looks like this

class TaskClass: Object {
    @objc dynamic var _id  = ObjectId.generate()
    @objc dynamic var _partitionKey = ""
}

and the _partitionKey is

"owner=julien,category=cat_a"

there will be a local filename matching that string

%22owner%3Djulien%2Ccategory%3Dcat_a%22

When creating the connection to Realm, the _partitionKey would have to match that

let config = user.configuration(partitionValue: "owner=julien,category=cat_a")
Realm.asyncOpen(configuration: config) { result in

Otherwise Realm wouldn’t know which file to open.

I would suggest changing the object structure to have the category as a property

class TaskClass: Object {
    @objc dynamic var _id  = 
    @objc dynamic var _partitionKey = "" //the users uid
    @objc dynamic var category = ""
}

If the categories are hard coded or stored in a list, you could concatenate the category with the owners id to have them all open at one time - that would give you access to all of them but they would each be in separate Results objects.

One other option is to denormalize your data - essentially keeping duplicate data in another Realm using the users uid as the _partitionKey. Upside is you can query across all categories (if that is the use case) but downside is more code to maintain and duplicate data.

Hi @Jay,

Thanks for your answer!

However I don’t understand when you said:

Can you please give me an example?

My comment was a bit unclear - sorry. I was simply stating that if you needed to open a connection to 5 realms you could iterate over an array of collection names and open each one.

for catName in ["cat_0", "cat_1"] {
   let partition = "\(userId),category=\(catName)"
   //open a realm using the partition string
}

Yes I was first thinking of doing it that way but I though that maybe there was a more efficient way I didn’t know.

Thanks for your help :slight_smile: