Navigation

Query Engine

To filter data in your realm, you can leverage Realm Database's query engine. Realm Database's query engine uses a Fluent interface to construct multi-clause queries. See RealmQuery API for a complete list of available methods.

There are several types of operators available to filter a Realm collection. Filters work by evaluating an operator expression for every object in the collection being filtered. If the expression resolves to true, Realm Database includes the object in the results collection.

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).
  • A literal string, number, or date.
Info With Circle IconCreated with Sketch.Note
About the examples on this page

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.

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

open class ProjectTask(
@Required
var name: String = "",
var assignee: String? = null,
var progressMinutes: Int = 0,
var isComplete: Boolean = false,
var priority: Int = 0,
var _partition: String = ""
): RealmObject()
open class Project(
@Required
var name: String = "",
var tasks: RealmList<ProjectTask> = RealmList(),
var _partition: String = ""
): RealmObject()

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

OperatorDescription
betweenEvaluates 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.
equalTo
Evaluates to true if the left-hand expression is equal to the right-hand expression.
greaterThan
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.
greaterThanOrEqualTo
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.
inEvaluates to true if the left-hand expression is in the right-hand list.
lessThan
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.
lessThanOrEqualTo
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.
notEqualTo
Evaluates to true if the left-hand expression is not equal to the right-hand expression.
Beaker IconExample

The following example uses 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.
val tasksQuery = realm.where<ProjectTask>()
Log.i("EXAMPLE", "High priority tasks: " + tasksQuery.greaterThan("priority", 5).count())
Log.i("EXAMPLE", "Just-started or short tasks: " + tasksQuery.between("progressMinutes", 1, 10).count())
Log.i("EXAMPLE", "Unassigned tasks: " + tasksQuery.isNull("assignee").count())
Log.i("EXAMPLE", "Ali or Jamie's tasks: " + tasksQuery.`in`("assignee", arrayOf("Ali", "Jamie")).count())

You can make compound predicates using logical operators.

OperatorDescription
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.
Beaker IconExample

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:

val tasksQuery = realm.where<ProjectTask>()
Log.i("EXAMPLE", "Ali has completed " +
tasksQuery.equalTo("assignee", "Ali").and().equalTo("isComplete", true).findAll().count() +
" tasks.")

You can compare string values using these string operators. Regex-like wildcards allow more flexibility in search.

OperatorDescription
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 left-hand string expression is found at the beginning of the right-hand string expression.
containsEvaluates to true if the left-hand string expression is found anywhere in the right-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".

equalTo
Evaluates to true if the left-hand string is lexicographically equal to the right-hand string.
Beaker IconExample

We use the query engine's string operators to find projects with a name starting with the letter 'e' and projects with names that contain 'ie':

val projectsQuery = realm.where<Project>()
// Pass Case.INSENSITIVE as the third argument for case insensitivity.
Log.i(TAG, "Projects that start with 'e': "
+ projectsQuery.beginsWith("name", "e", Case.INSENSITIVE).count())
Log.i(TAG, "Projects that contain 'ie': "
+ projectsQuery.contains("name", "ie").count())

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

OperatorDescription
average
Evaluates to the average value of a given numerical property across a collection.
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.
min
Evaluates to the lowest value of a given numerical property across a collection.
sum
Evaluates to the sum of a given numerical property across a collection.
Beaker IconExample

We create a couple of filters to show different facets of the data:

  • Projects with average tasks priority above 5.
  • Long running projects.
val tasksQuery = realm.where<ProjectTask>()
/* Aggregate operators do not support dot-notation, so you cannot directly operate on a property of all of the objects in a collection property. You can operate on a numeric property of the top-level object, however: */
Log.i("EXAMPLE", "Tasks average priority: " + tasksQuery.average("priority"))
  • There are several categories of operators available to filter results: comparison, logical, string and aggregate operators.
Give Feedback