You can, of course, easily read back the data that you have stored in Realm Database. The standard data access pattern across MongoDB Realm SDKs is to find, filter, and sort objects, in that order. To get the best performance from MongoDB Realm as your app grows and your queries become more complex, design your app’s data access patterns around a solid understanding of Realm Database read characteristics.

Read from Realm Database

A read from a realm generally consists of the following steps:

All query, filter, and sort operations return a results collection. The results collections are live, meaning they always contain the latest results of the associated query.

About the examples on this page

The examples on this page use the data model of a project management app that has two Realm object types: Project and Task. A Project has zero or more Tasks.

See the schema for these two classes, Project and Task, below:

class Task: Object {
    @objc dynamic var name = ""
    @objc dynamic var isComplete = false
    @objc dynamic var assignee: String? = nil
    @objc dynamic var priority = 0;
    @objc dynamic var progressMinutes = 0;

class Project: Object {
    @objc dynamic var name = ""
    let tasks = List<Task>();
// Task.h
@interface Task : RLMObject
@property NSString *name;
@property bool isComplete;
@property NSString *assignee;
@property int priority;
@property int progressMinutes;


// Task.m
@implementation Task

// Project.h
@interface Project : RLMObject
@property NSString *name;
@property RLMArray<Task> *tasks;

// Project.m
@implementation Project

Get All Objects

The first step of any read is to get all objects of a certain type in a realm. With this results collection, you can operate on all instances on a type or filter and sort to refine the results.


In order to access all instances of Project and Task, use the following syntax:

let projects = realm.objects(Project.self);
let tasks = realm.objects(Task.self);
RLMResults *projects = [Project allObjectsInRealm:realm];
RLMResults *tasks = [Task allObjectsInRealm:realm];

Filter Results

A filter selects a subset of results based on the value(s) of one or more object properties. Realm Database provides a full-featured query engine you can use to define filters. The most common use case is to find objects where a certain property matches a certain value. Additionally, you can compare strings, aggregate over collections of numbers, and use logical operators to build up complex queries.


In the following example, we use the query engine’s comparison operators to:

  • Find high priority tasks by comparing the value of the priority property value with a threshold number, above which priority can be considered high.
  • Find just-started or short-running tasks by seeing if the progressMinutes property falls within a certain range.
  • Find unassigned tasks by finding tasks where the assignee property is equal to null.
  • Find tasks assigned to specific teammates Ali or Jamie by seeing if the assignee property is in a list of names.
print("High priority tasks: \(tasks.filter("priority > 5").count)");
print("Long running tasks: \(tasks.filter("progressMinutes > 120").count)");
print("Unassigned tasks: \(tasks.filter("assignee == nil").count)");
print("Ali or Jamie's tasks: \(tasks.filter("assignee IN {'Ali', 'Jamie'}").count)");
NSLog(@"High priority tasks: %lu",
  [[tasks objectsWhere:@"priority > 5"] count]);

NSLog(@"Short running tasks: %lu",
  [[tasks objectsWhere:@"progressMinutes between {1, 15}"] count]);

NSLog(@"Unassigned tasks: %lu",
  [[tasks objectsWhere:@"assignee == nil"] count]);

NSLog(@"Ali or Jamie's tasks: %lu",
  [[tasks objectsWhere:@"assignee IN {'Ali', 'Jamie'}"] count]);

Sort Results

A sort operation allows you to configure the order in which Realm Database returns queried objects. You can sort based on one or more properties of the objects in the results collection.

Realm Database only guarantees a consistent order of results when the results are sorted.


The following code sorts the projects by name in reverse alphabetical order (i.e. “descending” order).

let projectsSorted = projects.sorted(byKeyPath: "name", ascending: false)

// You can also sort on the members of linked objects. In this example,
// we sort the dogs by dog's owner's name.
let dogs = realm.objects(Dog.self)
let ownersByName = dogs.sorted(byKeyPath: "")
RLMResults *projectsSorted = [projects sortedResultsUsingKeyPath:@"name" ascending:NO];

// You can also sort on the members of linked objects. In this example,
// we sort the dogs by dog's owner's name.
RLMResults *dogs = [Dog allObjectsInRealm:realm];
RLMResults *ownersByName = [dogs sortedResultsUsingKeyPath:@"" ascending:YES];

Read Characteristics

When you design your app’s data access patterns around the following three key characteristics of reads in Realm Database, you can be confident you are reading data as efficiently as possible.

Results Are Not Copies

Results to a query are not copies of your data: modifying the results of a query will modify the data on disk directly. This memory mapping also means that results are live: that is, they always reflect the current state on disk.

See also: Collections are Live.

Results Are Lazy

Realm Database defers execution of a query until you access the results. You can chain several filter and sort operations without requiring extra work to process the intermediate state.

See also: Results are Lazily Evaluated.

References Are Retained

One benefit of Realm Database’s object model is that Realm Database automatically retains all of an object’s relationships as direct references, so you can traverse your graph of relationships directly through the results of a query.

A direct reference, or pointer, allows you to access a related object’s properties directly through the reference.

Other databases typically copy objects from database storage into application memory when you need to work with them directly. Because application objects contain direct references, you are left with a choice: copy the object referred to by each direct reference out of the database in case it’s needed, or just copy the foreign key for each object and query for the object with that key if it’s accessed. If you choose to copy referenced objects into application memory, you can use up a lot of resources for objects that are never accessed, but if you choose to only copy the foreign key, referenced object lookups can cause your application to slow down.

Realm Database bypasses all of this using zero-copy live objects. Realm object accessors point directly into database storage using memory mapping, so there is no distinction between the objects in Realm Database and the results of your query in application memory. Because of this, you can traverse direct references across an entire realm from any query result.


  • To read from Realm Database, first get all objects of a certain type from the realm, then filter using the query engine, then (optionally) sort the results.
  • When you read, the results are not copies. Instead, through memory mapping, results point directly to the version on disk.
  • Queries are lazily-evaluated.
←   Writes Query Engine  →