Query Engine - .NET SDK
On this page
To filter data in your realm, use the Realm Database query engine.
There are two ways to use the query engine with the .NET SDK:
You should use LINQ syntax for querying when possible, as it aligns with .NET conventions.
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:
public class Task : RealmObject { [ ] [ ] public ObjectId Id { get; set; } = ObjectId.GenerateNewId(); public string Name { get; set; } public string Assignee { get; set; } public bool IsComplete { get; set; } public int Priority { get; set; } public int ProgressMinutes { get; set; } } public class Project : RealmObject { [ ] [ ] public ObjectId ID { get; set; } = ObjectId.GenerateNewId(); public string Name { get; set; } public IList<Task> Tasks { get; } }
LINQ Syntax
Realm Database's query engine implements standard LINQ syntax. See the scope of LINQ implemented on the LINQ Support page.
There are several operators available to filter a
Realm collection with LINQ.
Filters work by evaluating an operator expression for
every object in the collection being
filtered. If the expression resolves to true
, realm
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
- A value of any type used by realm (string, date, number, boolean, etc.)
Comparison Operators
Value comparisons
Operator | Description |
---|---|
== | 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. |
< | 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. |
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 tonull
. - Find tasks assigned to specific teammates Ali or Jamie by seeing if the
assignee
property is in a list of names.
var highPri = tasks.Where(t => t.Priority > 5); var quickTasks = tasks.Where(t => t.ProgressMinutes >= 1 && t.ProgressMinutes < 15); var unassignedTasks = tasks.Where(t => t.Assignee == null); var AliOrJamieTasks = tasks.Where(t => t.Assignee == "Ali" || t.Assignee == "Jamie");
Logical Operators
You can use the logical operators listed in the following table to make compound predicates:
Operator | Description |
---|---|
&& | Evaluates to true if both left-hand and right-hand expressions are
true . |
! | Negates the result of the given expression. |
|| | Evaluates to true if either expression returns true . |
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
:
var completedTasksForAli = tasks.Where(t => t.Assignee == "Ali" && t.IsComplete);
String Operators
You can compare string values using the string operators listed in the following table. Regex-like wildcards allow more flexibility in search.
Operator | Description |
---|---|
StartsWith | 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. |
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
For example, the wildcard string "d?g" matches "dog", "dig", and "dug", but not "ding", "dg", or "a dog". |
Equals | Evaluates to true if the left-hand string is
lexicographically
equal to the right-hand string. |
Contains | Evaluates to true if the left-hand string expression is found anywhere
in the right-hand string expression. |
string.IsNullOrEmpty | Evaluates to true if the left-hand string expression is null or empty.
Note that IsNullOrEmpty() is a static method on string . |
The following examples use the query engine's string operators to find tasks:
// Note: In each of the following examples, you can replace the // Where() method with First(), FirstOrDefault(), // Single(), SingleOrDefault(), // Last(), or LastOrDefault(). // Get all tasks where the Assignee's name starts with "E" or "e" var tasksStartWitE = tasks.Where(t => t.Assignee.StartsWith("E", StringComparison.OrdinalIgnoreCase)); // Get all tasks where the Assignee's name ends wth "is" // (lower case only) var endsWith = tasks.Where(t => t.Assignee.EndsWith("is", StringComparison.Ordinal)); // Get all tasks where the Assignee's name contains the // letters "ami" in any casing var tasksContains = tasks.Where(t => t.Assignee.Contains("ami", StringComparison.OrdinalIgnoreCase)); // Get all tasks that have no assignee var null_or_empty = tasks.Where(t => string.IsNullOrEmpty(t.Assignee));
When evaluating strings, the second parameter in all functions except Like
must be either StringComparison.OrdinalIgnoreCase
or
StringComparison.Ordinal
. For the Like()
method, the second
parameter is a boolean value (where "true" means "case sensitive").
Realm Query Language
You can also use Filter() to query realms using Realm Query Language. Realm Query Language is a string-based query language to access the query engine.
var elvisProjects = projects.Filter("Tasks.Assignee == 'Elvis'");
You should use .NET LINQ syntax for queries, unless your requirements extend beyond LINQ's current capabilities. Realm Query Language is able to perform operations that LINQ syntax is not, such as aggregation.
Refer to the Realm Query Language Reference for more information about syntax, usage and limitations.
You can also find useful Realm Query Language examples on the following pages:
Aggregate Operators
Aggregate operators traverse a
collection and reduce it
to a single value. Note that aggregations use the
Filter()
method, which can be used to create more complex queries that are currently
unsupported by the LINQ provider. Filter()
supports SORT and DISTINCT
clauses in addition to filtering.
You can apply any of the following aggregate operators:
Operator | Description |
---|---|
@avg | Evaluates to the average value of a given numerical property across a collection. |
@count | Evaluates to the number of objects in the given collection. This
is currently only supported on to-many relationship
collections and not on lists of
primitives. In order to use @count on a list of primitives,
consider wrapping the primitives in a Realm
object. |
@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. |
The following examples show different ways to aggregate data:
// Get all projects with an average Task priorty > 5: var avgPriority = projects.Filter( "Tasks.@avg.Priority > 5"); // Get all projects where all Tasks are high-priority: var highPriProjects = projects.Filter( "Tasks.@min.Priority > 5"); // Get all projects with long-running Tasks: var longRunningProjects = projects.Filter( "Tasks.@sum.ProgressMinutes > 100");