Docs Menu

Realm Query Language

On this page

Realm Query Language (RQL) is a string-based query language to constrain searches when retrieving objects from a realm. SDK-specific methods pass queries to the Realm query engine, which retrieves matching objects from the realm. Realm Query Language syntax is based on NSPredicate.

Queries evaluate a predicate for every object in the collection being queried. If the predicate resolves to true, the results collection includes the object.

You can use Realm Query Language in most Realm SDKs with your SDK's filter or query methods. The Swift SDK is the exception, as it uses the NSPredicate query API. Some SDKs also support idiomatic APIs for querying realms in their language.

For further reading on SDK-specific methods for querying realms, select the tab below for your SDK.

You can also use Realm Query Language to browse for data in Realm Studio. Realm Studio is a visual tool to view, edit, and design Realm Database files.

Many of the examples in this page use a simple data set for a task list app. The two Realm object types are Project and Task.

  • A Task has a name, assignee's name, and completed flag. There is also an arbitrary number for priority (higher is more important) and a count of minutes spent working on it.
  • A Project has zero or more Tasks and an optional quota for minimum number of tasks expected to be completed.

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

Filters consist of expressions in a predicate. An expression consists of one of the following:

  • The name of a property of the object currently being evaluated.
  • An operator and up to two argument expression(s). For example, in the expression A + B, the entirety of A + B is an expression, but A and B are also argument expressions to the operator +.
  • A value, such as a string ('hello') or a number (5).
"progressMinutes > 1 AND assignee == $0", "Ali"

Create parameterized queries to interpolate variables into prepared Realm Query Language statements. The syntax for interpolated variables is $<int>, starting at 0. Pass the positional arguments as additional arguments to Realm SDK methods that use Realm Query Language.

Include just one parameter with $0.

"progressMinutes > 1 AND assignee == $0", "Ali"

Include multiple parameters with ascending integers starting at $0.

"progressMinutes > $0 AND assignee == $1", 1, "Alex"

When referring to an object property, you can use dot notation to refer to child properties of that object. You can even refer to the properties of embedded objects and relationships with dot notation.

For example, consider a query on an object with a workplace property that refers to a Workplace object. The Workplace object has an embedded object property, address. You can chain dot notations to refer to the zipcode property of that address:

"workplace.address.zipcode == 10019"

The most straightforward operation in a search is to compare values.

Important
Types Must Match

The type on both sides of the operator must be equivalent. For example, comparing an ObjectId with string will result in a precondition failure with a message like:

"Expected object of type object id for property 'id' on object of type
'User', but received: 11223344556677889900aabb (Invalid value)"

You can compare any numeric type with any other numeric type, including decimal, float, and Decimal128.

Operator
Description
BETWEEN {number1, number2}
Evaluates to true if the left-hand numerical or date expression is between or equal to the right-hand range. For dates, this evaluates to true if the left-hand date is within the right-hand date range.
==, =
Evaluates to true if the left-hand expression is equal to the right-hand expression.
>
Evaluates to true if the left-hand numerical or date expression is greater than the right-hand numerical or date expression. For dates, this evaluates to true if the left-hand date is later than the right-hand date.
>=
Evaluates to true if the left-hand numerical or date expression is greater than or equal to the right-hand numerical or date expression. For dates, this evaluates to true if the left-hand date is later than or the same as the right-hand date.
IN
Evaluates to true if the left-hand expression is in the right-hand list or string.
<
Evaluates to true if the left-hand numerical or date expression is less than the right-hand numerical or date expression. For dates, this evaluates to true if the left-hand date is earlier than the right-hand date.
<=
Evaluates to true if the left-hand numeric expression is less than or equal to the right-hand numeric expression. For dates, this evaluates to true if the left-hand date is earlier than or the same as the right-hand date.
!=, <>
Evaluates to true if the left-hand expression is not equal to the right-hand expression.
Example

The following example uses Realm Query Language'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 long-running tasks by seeing if the progressMinutes property is at or above a certain value.
  • Find unassigned tasks by finding tasks where the assignee property is equal to null.
  • Find tasks within a certain time range by finding tasks where the progressMinutes property is between two numbers.
"priority > 5"
"progressMinutes > 120"
"assignee == nil"
"progressMinutes BETWEEN { 30,60 }"

Make compound predicates using logical operators.

Operator
Description
AND
&&
Evaluates to true if both left-hand and right-hand expressions are true.
NOT
!
Negates the result of the given expression.
OR
||
Evaluates to true if either expression returns true.
Example

We can use the query language's logical operators to find all of Ali's completed tasks. That is, we find all tasks where the assignee property value is equal to 'Ali' AND the isComplete property value is true:

"assignee == 'Ali' AND isComplete == true"

Compare string values using these string operators. Regex-like wildcards allow more flexibility in search.

Note

You can use the following modifiers with the string operators:

  • [c] for case insensitivity.

    "name CONTAINS[c] 'a'"
Operator
Description
BEGINSWITH
Evaluates to true if the left-hand string expression begins with the right-hand string expression. This is similar to contains, but only matches if the right-hand string expression is found at the beginning of the left-hand string expression.
IN
Evaluates to true if the left-hand string expression is found anywhere in the right-hand string expression.
CONTAINS
Evaluates to true if the right-hand string expression is found anywhere in the left-hand string expression.
ENDSWITH
Evaluates to true if the left-hand string expression ends with the right-hand string expression. This is similar to contains, but only matches if the left-hand string expression is found at the very end of the right-hand string expression.
LIKE

Evaluates to true if the left-hand string expression matches the right-hand string wildcard string expression. A wildcard string expression is a string that uses normal characters with two special wildcard characters:

  • The * wildcard matches zero or more of any character
  • The ? wildcard matches any character.

For example, the wildcard string "d?g" matches "dog", "dig", and "dug", but not "ding", "dg", or "a dog".

==, =
Evaluates to true if the left-hand string is lexicographically equal to the right-hand string.
!=, <>
Evaluates to true if the left-hand string is not lexicographically equal to the right-hand string.
Example

We use the query engine's string operators to find:

  • Projects with a name starting with the letter 'e'
  • Projects with names that contain 'ie'
"name BEGINSWITH[c] 'e'"
"name CONTAINS 'ie'"

Query BSON ObjectIds and UUIDs. These data types are often used as primary keys.

To query with ObjectIds, use a parameterized query. Pass the ObjectId or UUID you're querying against as the argument.

"_id == $0", oidValue

You can also put a string representation of the ObjectId you're evaluating in oid(<ObjectId String>).

"_id == oid(6001c033600510df3bbfd864)"

To query with UUIDs, put a string representation of the UUID you're evaluating in uuid(<UUID String>).

"id == uuid(d1b186e1-e9e0-4768-a1a7-c492519d47ee)"
Operator
Description
==, =
Evaluates to true if the left-hand value is equal to the right-hand value.
!=, <>
Evaluates to true if the left-hand value is not equal to the right-hand value.

Perform basic arithmetic in one side of a RQL expression when evaluating numeric data types.

"2 * priority > 6"
// Is equivalent to
"priority >= 2 * (2 - 1) + 2"

You can also use multiple object properties together in a mathematic operation.

"progressMinutes * priority == 90"
Operator
Description
*
Multiplication.
/
Division.
+
Addition.
-
Subtraction.
()
Group expressions together.

Check the type of a property using the @type operator. You can only use the type operator with mixed types and dictionaries.

Evaluate the property against a string representation of the data type name. Refer to SDK documentation on the mapping from the SDK language's data types to Realm data types.

Operator
Description
@type
Check if type of a property is the property name as a string. Use == and != to compare equality.
"mixedType.@type == 'string'"
"mixedType.@type == 'bool'"

Compare dictionary values using these dictionary operators.

Operator
Description
@values
Returns objects that have the value specified in the right-hand expression.
@keys
Returns objects that have the key specified in the right-hand expression.
@size, @count
The number of elements in a dictionary.
Dictionary['key']
Access the value at a key of a dictionary.
ALL | ANY | NONE <property>.@type
Checks if the dictionary contains properties of certain type.

You can also use dictionary operators in combination with comparison operators to filter objects based on dictionary keys and values. The following examples show some ways to use dictionary operators with comparison operators. All examples query a collection of Realm objects with a dictionary property named dict.

Example

The following examples use various dictionary operators.

// Evaluates if there is a dictionary key with the name 'foo'
"ANY dict.@keys == 'foo'"
// Evaluates if there is a dictionary key with key 'foo' and value 'bar
"dict['foo'] == 'bar'"
// Evaluates if there is a dictionary key with key 'foo' and value 'bar
"dict.@count > 1"
// Evaluates if dictionary has property of type 'string'
"ANY dict.@type == 'string'"
// Evaluates if all the dictionary's values are integers
"ALL dict.@type == 'bool'"
// Evaluates if dictionary does not have any values of type int
"NONE dict.@type == 'double'"
// ANY is implied.
"dict.@type == 'string'"

Query date types in a realm.

Generally, you should use parameterized query to pass a date data type from the SDK language you are using to a query.

"timeCompleted < $0", someDate

You can also represent dates the following ways:

  • YYYY-MM-DD@HH:mm:ss:nnnnnnnnnn (year-month-day@hours:minutes:seconds:nanoseconds), UTC. You can also use T instead of @ to separate the date from the time.
  • Ts:n, where s is the number of seconds and n the number of nanoseconds since unix epoch.

Date supports comparison operators.

Example

The following example shows how to compare dates with their different representations.

"timeCompleted > 2021-02-20@17:30:15:0"
"timeCompleted > 2021-02-20@17:30:15:0"

Apply an aggregate operator to a collection property of a Realm object. Aggregate operators traverse a collection and reduce it to a single value.

Operator
Description
@avg
Evaluates to the average value of a given numerical property across a collection. If any values are null, they are not counted in the result.
@count
Evaluates to the number of objects in the given collection.
@max
Evaluates to the highest value of a given numerical property across a collection. null values are ignored.
@min
Evaluates to the lowest value of a given numerical property across a collection. null values are ignored.
@sum
Evaluates to the sum of a given numerical property across a collection, excluding null values.
Example

These examples all query for projects containing tasks that meet this criteria:

  • Projects with average task priority above 5.
  • Projects with a task whose priority is less than 5.
  • Projects with a task whose priority is greater than 5.
  • Projects with more than 5 tasks.
  • Projects with long-running tasks.
"tasks.@avg.priority > 5"
"tasks.@max.priority < 5"
"tasks.@min.priority > 5"
"tasks.@count > 5"
"tasks.@sum.progressMinutes > 100"

A collection operator lets you query list properties within a collection of objects. Collection operators filter a collection by applying a predicate to every element of a given list property of the object. If the predicate returns true, the object is included in the output collection.

Operator
Description
ALL
Returns objects where the predicate evaluates to true for all objects in the collection.
ANY, SOME
Returns objects where the predicate evaluates to true for any objects in the collection.
NONE
Returns objects where the predicate evaluates to false for all objects in the collection.
Example

This example uses collection operators to find projects that contain tasks matching certain criteria:

// Projects with no complete tasks.
"NONE tasks.isComplete == true"
// Projects that contain a task with priority 10
"ANY tasks.priority == 10"
// Projects that only contain completed tasks
"ALL tasks.isComplete == true"

Iterate through list properties with another query using the SUBQUERY() predicate function.

Subqueries are useful for the following scenarios:

  • Matching each object in a list property on multiple conditions
  • Counting the number of objects that match a subquery

SUBQUERY() has the following structure:

SUBQUERY(<collection>, <variableName>, <predicate>)
  • collection: The name of the property to iterate through
  • variableName: A variable name of the element to use in the subquery
  • predicate: The subquery predicate. Use the variable specified by variableName to refer to the currently-iterated element.

A subquery iterates through the given collection and checks the given predicate against each object in the collection. The predicate can refer to the current iterated object with the variable name passed to SUBQUERY().

A subquery expression resolves to a list of objects. Realm Database only supports the @count aggregate operator on the result of a subquery. This allows you to count how many objects in the subquery input collection matched the predicate.

You can use the count of the subquery result as you would any other number in a valid expression. In particular, you can compare the count with the number 0 to return all matching objects.

Example

The following example shows two subquery filters on a collection of projects.

// Returns projects with tasks that have not been completed
// by a user named Alex.
"SUBQUERY(tasks, $task, $task.isComplete == false AND $task.assignee == 'Alex').@count > 0"
// Returns the projects where the number of completed tasks is
// greater than or equal to the value of a project's `quota` property.
"SUBQUERY(tasks, $task, $task.isComplete == true).@count >= quota"

Sort and limit the results collection of your query using additional operators.

Operator
Description
SORT
Specify the name of the property to compare. You can optionally specify ascending (ASC) or descending (DESC) order. If you specify multiple SORT fields, the query sorts by the first field, and then the second. For example, if you SORT (priority, name), the query returns sorted by priority, and then by name when priority value is the same.
DISTINCT
Specify a name of the property to compare. Remove duplicates for that property in the results collection. If you specify multiple DISTINCT fields, the query removes duplicates by the first field, and then the second. For example, if you DISTINCT (name, assignee), the query only removes duplicates where the values of both properties are the same.
LIMIT
Limit the results collection to the specified number.
Example

Use the query engine's sort, distinct, and limit operators to find tasks where the assignee is Ali:

  • Sorted by priority in descending order
  • Enforcing uniqueness by name
  • Limiting the results to 5 tasks
"assignee = 'Ali' SORT(priority DESC) DISTINCT(name) LIMIT(5)"

Flexible Sync has some limitations when using RQL operators. When you write the query subscription that determines which data to sync, the server does not support these query operators. However, you can still use the full range of RQL features to query the synced data set in the client application.

Operator Type
Unsupported Operators
String Operators
in
Aggregate Operators
@avg, @count, @max, @min, @sum
Query Suffixes
DISTINCT, SORT, LIMIT

Case insensitive queries ([c]) cannot use indexes effectively. As a result, case insensitive queries are not recommended, since they could lead to performance problems.

Flexible Sync only supports @count for array fields.

Flexible Sync does not support querying on properties in Embedded Objects or links. For example, obj1.field = “foo”.

←  Modify Schema in a Realm StudioGet Help →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.