Docs Menu
Docs Home
/ /
CRUD

Filtrar datos - Swift SDK

Para filtrar datos en su ámbito, puede aprovechar el motor de consulta de Realm.

Novedades de la 10.19.0 versión: API de consulta Swift de Realm

El La API de consulta de Realm Swift ofrece a los desarrolladores de Swift una forma idiomática de consultar datos. Utilice la sintaxis de estilo Swift para consultar un realm con las ventajas del autocompletado y la seguridad de tipos. La API de consulta de Realm Swift no reemplaza a la API de consulta NSPredicate en las versiones más recientes del SDK; puede usar cualquiera de las dos.

Para las versiones del SDK anteriores 10.19.0 a, o para desarrolladores de Objective-C, el motor de consulta de Realm admite NSPredicate Query.

Los ejemplos de esta página utilizan un conjunto de datos simple para una aplicación de lista de tareas. Los dos tipos de objetos Realm son Project y Task. Un Task tiene un nombre, el nombre del asignado y un indicador de finalización. También hay un número arbitrario para la prioridad (cuanto más alto, más importante) y un recuento de minutos dedicados a trabajar en él. Finalmente, un Task puede tener una o más cadenas labels y uno o más enteros ratings.

Un Project tiene cero o más Tasks.

Vea el esquema de estas dos clases, Project y Task, a continuación:

// Task.h
@interface Task : RLMObject
@property NSString *name;
@property bool isComplete;
@property NSString *assignee;
@property int priority;
@property int progressMinutes;
@end
RLM_COLLECTION_TYPE(Task)
// Task.m
@implementation Task
@end
// Project.h
@interface Project : RLMObject
@property NSString *name;
@property RLMArray<Task> *tasks;
@end
// Project.m
@implementation Project
@end
class Task: Object {
@Persisted var name = ""
@Persisted var isComplete = false
@Persisted var assignee: String?
@Persisted var priority = 0
@Persisted var progressMinutes = 0
@Persisted var labels: MutableSet<String>
@Persisted var ratings: MutableSet<Int>
}
class Project: Object {
@Persisted var name = ""
@Persisted var tasks: List<Task>
}

Puede configurar el reino para estos ejemplos con el siguiente código:

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^() {
// Add projects and tasks here
}];
RLMResults *tasks = [Task allObjectsInRealm:realm];
RLMResults *projects = [Project allObjectsInRealm:realm];
let realm = try! Realm()
try! realm.write {
// Add tasks and projects here.
let project = Project()
project.name = "New Project"
let task = Task()
task.assignee = "Alex"
task.priority = 5
project.tasks.append(task)
realm.add(project)
// ...
}
let tasks = realm.objects(Task.self)
let projects = realm.objects(Project.self)

Novedad en la 10.19.0 versión: para versiones del SDK anteriores 10.19.0 a, utilice la API de consulta NSPredicate.

Puede crear un filtro con sintaxis de estilo Swift utilizando la .where API de consulta Swift de Realm:

let realmSwiftQuery = projects.where {
($0.tasks.progressMinutes > 1) && ($0.tasks.assignee == "Ali")
}

Esta API de consulta construye un NSPredicate para ejecutar la consulta. Ofrece a los desarrolladores una API idiomática con seguridad de tipos para usar directamente y abstrae la construcción de NSPredicate.

La API .where recibe una devolución de llamada que evalúa como verdadera o falsa. Esta devolución de llamada recibe una instancia del tipo consultado, y se puede usar el compilador para comprobar estáticamente que se están creando consultas válidas que hacen referencia a propiedades válidas.

En los ejemplos de esta página, utilizamos la abreviatura $0 para hacer referencia a la variable pasada a la devolución de llamada.

Hay varios tipos de operadores disponibles para consultar una colección de Realm. Las queries funcionan evaluando una expresión de operador para cada objeto en la colección consultada. Si la expresión se resuelve en true, Realm base de datos incluye el objeto en la colección de resultados.

Puede utilizar operadores de comparación Swift con la API de consulta Swift de Realm (==, !=, >, >=, <, <=).

Ejemplo

El siguiente ejemplo utiliza los operadores de comparación del motor de consulta para:

  • Encuentre tareas de alta prioridad comparando el valor de la propiedad priority con un número umbral, por encima del cual la prioridad puede considerarse alta.

  • Encuentre tareas de larga ejecución viendo si la propiedad progressMinutes está en un valor determinado o por encima de él.

  • Encuentre tareas no asignadas buscando tareas donde la propiedad assignee sea igual a null.

let highPriorityTasks = tasks.where {
$0.priority > 5
}
print("High-priority tasks: \(highPriorityTasks.count)")
let longRunningTasks = tasks.where {
$0.progressMinutes >= 120
}
print("Long running tasks: \(longRunningTasks.count)")
let unassignedTasks = tasks.where {
$0.assignee == nil
}
print("Unassigned tasks: \(unassignedTasks.count)")

Puedes consultar valores dentro de una colección usando los operadores .contains. Puedes buscar valores individuales por elemento o dentro de un rango.

Operador
Descripción
.in(_ collection:)

Se evalúa como true si la propiedad a la que hace referencia la expresión contiene un elemento en la matriz dada.

.contains(_ element:)

Equivalente al operador IN. Se evalúa como true si la propiedad referenciada por la expresión contiene el valor.

.contains(_ range:)

Equivalente al operador BETWEEN. Se evalúa como true si la propiedad referenciada por la expresión contiene un valor dentro del rango.

.containsAny(in: )

Equivalente al operador IN combinado con el operador ANY. Se evalúa como true si algún elemento del array dado está presente en la colección.

Ejemplo

  • Busque tareas donde la propiedad de colección MutableSet labels contenga "victoria rápida".

  • Busque tareas donde la propiedad progressMinutes esté dentro de un rango determinado de minutos.

let quickWinTasks = tasks.where {
$0.labels.contains("quick win")
}
print("Tasks labeled 'quick win': \(quickWinTasks.count)")
let progressBetween30and60 = tasks.where {
$0.progressMinutes.contains(30...60)
}
print("Tasks with progress between 30 and 60 minutes: \(progressBetween30and60.count)")

Busque tareas donde la propiedad de colección MutableSet labels contenga cualquiera de los elementos en la matriz dada: "quick win" o "bug".

let quickWinOrBugTasks = tasks.where {
$0.labels.containsAny(in: ["quick win", "bug"])
}
print("Tasks labeled 'quick win' or 'bug': \(quickWinOrBugTasks.count)")

Novedades en la 10.23.0 versión:: El IN operador

La API de consulta Swift de Realm ahora admite el operador IN. Se evalúa como true si la propiedad referenciada por la expresión contiene el valor.

Ejemplo

Encuentre tareas asignadas a compañeros de equipo específicos, Ali o Jamie, viendo si la propiedad assignee está en una lista de nombres.

let taskAssigneeInAliOrJamie = tasks.where {
let assigneeNames = ["Ali", "Jamie"]
return $0.assignee.in(assigneeNames)
}
print("Tasks IN Ali or Jamie: \(taskAssigneeInAliOrJamie.count)")

Puede realizar consultas compuestas utilizando operadores lógicos Swift (&&, !, ||).

Ejemplo

Podemos usar los operadores lógicos del lenguaje de consulta para encontrar todas las tareas completadas de Ali. Es decir, buscamos todas las tareas donde el valor de la propiedad assignee es igual a 'Ali' y el valor de la propiedad isComplete es true:

let aliComplete = tasks.where {
($0.assignee == "Ali") && ($0.isComplete == true)
}
print("Ali's complete tasks: \(aliComplete.count)")

Puedes comparar valores de cadena usando estos operadores. Los comodines tipo expresiones regulares ofrecen mayor flexibilidad en la búsqueda.

Nota

Puede utilizar las siguientes opciones con operadores de cadena:

  • .caseInsensitive por no distinguir entre mayúsculas y minúsculas.

    $0.name.contains("f", options: .caseInsensitive)
  • .diacriticInsensitive por insensibilidad diacrítica: Realm trata los caracteres especiales como el carácter base (por ejemplo, é -> e).

    $0.name.contains("e", options: .diacriticInsensitive)
Operador
Descripción
.starts(with value: String)

Se evalúa como true si la colección contiene un elemento cuyo valor comienza con el valor de cadena especificado.

.contains(_ value: String)

Evalúa como true si la expresión de string a la izquierda se encuentra en cualquier parte de la expresión de string a la derecha.

.ends(with value: String)

Se evalúa como true si la colección contiene un elemento cuyo valor termina con el valor de cadena especificado.

.like(_ value: String)

Se evalúa como true si la expresión de cadena de la izquierda coincide con la expresión de cadena comodín de la derecha. Una expresión de cadena comodín es una cadena que utiliza caracteres normales con dos caracteres comodín especiales:

  • El comodín * coincide con cero o más de cualquier carácter

  • El comodín ? coincide con cualquier carácter.

Por ejemplo, la cadena comodín "d?g" coincide con "perro", "dig" y "dug", pero no con "ding", "dg" o "un perro".

==

Se evalúa como true si la cadena de la izquierda es lexicográficamente igual a la cadena de la derecha.

!=

Se evalúa como true si la cadena de la izquierda no es lexicográficamente igual a la cadena de la derecha.

Ejemplo

El siguiente ejemplo utiliza los operadores de cadena del motor de consulta para buscar:

  • Proyectos con un nombre que empieza con la letra 'e'

  • Proyectos con nombres que contienen 'ie'

  • Proyectos con una propiedad assignee cuyo valor es similar a Al?x

  • Proyectos que contienen caracteres tipo e con insensibilidad diacrítica

// Use the .caseInsensitive option for case-insensitivity.
let startWithE = projects.where {
$0.name.starts(with: "e", options: .caseInsensitive)
}
print("Projects that start with 'e': \(startWithE.count)")
let containIe = projects.where {
$0.name.contains("ie")
}
print("Projects that contain 'ie': \(containIe.count)")
let likeWildcard = tasks.where {
$0.assignee.like("Al?x")
}
print("Tasks with assignees like Al?x: \(likeWildcard.count)")
// Use the .diacreticInsensitive option for diacritic insensitivty: contains 'e', 'E', 'é', etc.
let containElike = projects.where {
$0.name.contains("e", options: .diacriticInsensitive)
}
print("Projects that contain 'e', 'E', 'é', etc.: \(containElike.count)")

Nota

La ordenación de cadenas y las consultas sin distinción entre mayúsculas y minúsculas solo se admiten para los conjuntos de caracteres en 'Latin Basic', 'Latin Supplement', 'Latin Extended A' y 'Latin Extended B' (UTF-8 rango 0-591).

Nuevo en la versión 10.47.0.

Utilice el operador geoWithin para consultar datos geoespaciales con una de las formas proporcionadas por el SDK:

  • GeoCircle

  • GeoBox

  • GeoPolygon

Este operador evalúa a true si:

  • Un objeto tiene una "forma" de datos geoespaciales que contiene una propiedad String con el valor de Punto y un List que contiene un par de longitud/latitud.

  • La longitud/latitud del objeto persistente cae dentro de la forma de consulta geoespacial.

let companiesInSmallCircle = realm.objects(Geospatial_Company.self).where {
$0.location.geoWithin(smallCircle!)
}
print("Number of companies in small circle: \(companiesInSmallCircle.count)")

Para obtener más información sobre cómo consultar datos geoespaciales, consulte Consultar datos geoespaciales.

Se puede aplicar un operador de agregación a una propiedad de colección de un objeto Realm. Los operadores de agregación recorren una colección y la reducen a un único valor.

Operador
Descripción
.avg

Se evalúa como el valor promedio de una propiedad numérica dada en una colección.

.count

Evalúa el número de objetos en la colección dada. Actualmente, esto solo se admite en colecciones con relaciones de varios a varios, no en listas de primitivas. Para usar .count en una lista de primitivas, considere encapsular las primitivas en un objeto Realm.

.max

Se evalúa como el valor más alto de una propiedad numérica dada en una colección.

.min

Se evalúa como el valor más bajo de una propiedad numérica dada en una colección.

.sum

Se evalúa como la suma de una propiedad numérica dada en una colección.

Ejemplo

Creamos un par de filtros para mostrar diferentes facetas de los datos:

  • Proyectos con prioridad de tareas promedio superior a 5.

  • Proyectos que contienen únicamente tareas de baja prioridad por debajo de 5.

  • Proyectos donde todas las tareas tienen una prioridad alta superior a 5.

  • Proyectos que contienen más de 5 tareas.

  • Proyectos de larga duración.

let averageTaskPriorityAbove5 = projects.where {
$0.tasks.priority.avg > 5
}
print("Projects with average task priority above 5: \(averageTaskPriorityAbove5.count)")
let allTasksLowerPriority = projects.where {
$0.tasks.priority.max < 5
}
print("Projects where all tasks are lower priority: \(allTasksLowerPriority.count)")
let allTasksHighPriority = projects.where {
$0.tasks.priority.min > 5
}
print("Projects where all tasks are high priority: \(allTasksHighPriority.count)")
let moreThan5Tasks = projects.where {
$0.tasks.count > 5
}
print("Projects with more than 5 tasks: \(moreThan5Tasks.count)")
let longRunningProjects = projects.where {
$0.tasks.progressMinutes.sum > 100
}
print("Long running projects: \(longRunningProjects.count)")

Un operador de conjunto utiliza reglas específicas para determinar si se debe pasar cada objeto de colección de entrada a la colección de salida aplicando una expresión de consulta determinada a cada elemento de una propiedad de lista determinada del objeto.

Ejemplo

Al ejecutar las siguientes consultas en projects colecciones, se devuelve lo siguiente:

  • Proyectos donde un conjunto de cadenas labels contiene cualquiera de los siguientes: "victoria rápida", "error".

  • Proyectos donde cualquier elemento de un conjunto de enteros ratings es mayor que 3.

let projectsWithGivenLabels = projects.where {
$0.tasks.labels.containsAny(in: ["quick win", "bug"])
}
print("Projects with quick wins: \(projectsWithGivenLabels.count)")
let projectsWithRatingsOver3 = projects.where {
$0.tasks.ratings > 3
}
print("Projects with any ratings over 3: \(projectsWithRatingsOver3.count)")

Puede iterar a través de una propiedad de colección con otra consulta mediante una subconsulta. Para formar una subconsulta, debe encerrar la expresión entre paréntesis e inmediatamente después el agregador .count.

(<query>).count > n

Si la expresión no produce una subconsulta válida, obtendrá una excepción en tiempo de ejecución.

Ejemplo

Ejecutar la siguiente query en una colección projects devuelve proyectos con tareas que no han sido completadas por un usuario llamado Alex.

let subquery = projects.where {
($0.tasks.isComplete == false && $0.tasks.assignee == "Alex").count > 0
}
print("Projects with incomplete tasks assigned to Alex: \(subquery.count)")

Puedes crear un filtro con NSPredicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"progressMinutes > %@ AND name == %@", @1, @"Ali"];
let predicate = NSPredicate(format: "progressMinutes > 1 AND name == %@", "Ali")

Los filtros consisten en expresiones en un NSPredicate. Una expresión consiste en uno de los siguientes elementos:

  • El nombre (ruta de clave) de una propiedad del objeto que se está evaluando actualmente.

  • Un operador y hasta dos expresiones de argumentos.

  • Un valor, como una cadena ('hello') o un número (5).

Al referirse a una propiedad de un objeto, se puede usar la notación de puntos para referirse a sus propiedades secundarias. Incluso se puede usar la notación de puntos para referirse a las propiedades de objetos incrustados y relaciones.

Por ejemplo, considere una consulta sobre un objeto con la propiedad workplace que hace referencia a un objeto Workplace. Este objeto tiene una propiedad de objeto incrustada, address. Puede encadenar notaciones de punto para hacer referencia a la propiedad de código postal de esa dirección:

workplace.address.zipcode == 10012

Puedes utilizar las siguientes sustituciones en tus cadenas de formato de predicado:

[NSPredicate predicateWithFormat:@"%K > %@ AND %K == %@", @"progressMinutes", @1, @"name", @"Ali"];
NSPredicate(format: "%K > %@ AND %K == %@", "progressMinutes", NSNumber(1), "name", "Ali")

Existen varios tipos de operadores disponibles para filtrar una colección de Realm. Los filtros funcionan evaluando una expresión de operador para cada objeto de la colección que se filtra. Si la expresión se resuelve true como, Realm Database incluye el objeto en la colección de resultados.

La operación más sencilla en una búsqueda es comparar valores.

Importante

Los tipos deben coincidir

El tipo en ambos lados del operador debe ser equivalente. Por ejemplo, comparar un ObjectId con una cadena generará un error de precondición con un mensaje como este:

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

Puede comparar cualquier tipo numérico con cualquier otro tipo numérico.

Operador
Descripción

between

Se evalúa como true si la expresión numérica o de fecha de la izquierda se encuentra dentro o es igual al rango de la derecha. Para las fechas, se evalúa como true si la fecha de la izquierda está dentro del rango de la derecha.

==, =

Se evalúa como true si la expresión de la izquierda es igual a la expresión de la derecha.

>

Se evalúa como true si la expresión numérica o de fecha de la izquierda es mayor que la de la derecha. Para las fechas, se evalúa como true si la fecha de la izquierda es posterior a la de la derecha.

>=

Se evalúa como true si la expresión numérica o de fecha de la izquierda es mayor o igual que la expresión numérica o de fecha de la derecha. Para las fechas, se evalúa como true si la fecha de la izquierda es posterior o igual a la de la derecha.

in

Se evalúa como true si la expresión de la izquierda está en la lista o cadena de la derecha.

<

Se evalúa como true si la expresión numérica o de fecha de la izquierda es menor que la de la derecha. Para las fechas, se evalúa como true si la fecha de la izquierda es anterior a la de la derecha.

<=

Se evalúa como true si la expresión numérica de la izquierda es menor o igual que la de la derecha. Para las fechas, se evalúa como true si la fecha de la izquierda es anterior o igual a la de la derecha.

!=, <>

Se evalúa como true si la expresión de la izquierda no es igual a la expresión de la derecha.

Ejemplo

El siguiente ejemplo utiliza los operadores de comparación del motor de consulta para:

  • Encuentre tareas de alta prioridad comparando el valor de la propiedad priority con un número umbral, por encima del cual la prioridad puede considerarse alta.

  • Encuentre tareas de larga ejecución viendo si la propiedad progressMinutes está en un valor determinado o por encima de él.

  • Encuentre tareas no asignadas buscando tareas donde la propiedad assignee sea igual a null.

  • Encuentre tareas asignadas a compañeros de equipo específicos, Ali o Jamie, viendo si la propiedad assignee está en una lista de nombres.

NSLog(@"High priority tasks: %lu",
[[tasks objectsWithPredicate:[NSPredicate predicateWithFormat:@"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]);
NSLog(@"Tasks with progress between 30 and 60 minutes: %lu",
[[tasks objectsWhere:@"progressMinutes BETWEEN {30, 60}"] count]);
let highPriorityTasks = tasks.filter("priority > 5")
print("High priority tasks: \(highPriorityTasks.count)")
let longRunningTasks = tasks.filter("progressMinutes > 120")
print("Long running tasks: \(longRunningTasks.count)")
let unassignedTasks = tasks.filter("assignee == nil")
print("Unassigned tasks: \(unassignedTasks.count)")
let aliOrJamiesTasks = tasks.filter("assignee IN {'Ali', 'Jamie'}")
print("Ali or Jamie's tasks: \(aliOrJamiesTasks.count)")
let progressBetween30and60 = tasks.filter("progressMinutes BETWEEN {30, 60}")
print("Tasks with progress between 30 and 60 minutes: \(progressBetween30and60.count)")

Puedes crear predicados compuestos utilizando operadores lógicos.

Operador
Descripción
and
&&

Se evalúa como true si las expresiones de la izquierda y la derecha son true.

not
!

Niega el resultado de la expresión dada.

or
||

Se evalúa como true si alguna expresión devuelve true.

Ejemplo

Podemos usar los operadores lógicos del lenguaje de consulta para encontrar todas las tareas completadas de Ali. Es decir, buscamos todas las tareas donde el valor de la propiedad assignee es igual a 'Ali' y el valor de la propiedad isComplete es true:

NSLog(@"Ali's complete tasks: %lu",
[[tasks objectsWhere:@"assignee == 'Ali' AND isComplete == true"] count]);
let aliComplete = tasks.filter("assignee == 'Ali' AND isComplete == true")
print("Ali's complete tasks: \(aliComplete.count)")

Puedes comparar valores de cadena usando estos operadores. Los comodines tipo expresiones regulares ofrecen mayor flexibilidad en la búsqueda.

Nota

Puede utilizar los siguientes modificadores con los operadores de cadena:

  • [c] por no distinguir entre mayúsculas y minúsculas.

    [NSPredicate predicateWithFormat: @"name CONTAINS[c] 'f'"]
    NSPredicate(format: "name CONTAINS[c] 'f'")
  • [d] por insensibilidad diacrítica: Realm trata los caracteres especiales como el carácter base (por ejemplo, é -> e).

    [NSPredicate predicateWithFormat: @"name CONTAINS[d] 'e'"]
    NSPredicate(format: "name CONTAINS[d] 'e'")
Operador
Descripción
beginsWith

Se evalúa como true si la expresión de cadena de la izquierda comienza con la expresión de cadena de la derecha. Es similar a contains, pero solo coincide si la expresión de cadena de la derecha se encuentra al principio de la expresión de cadena de la izquierda.

contains, in

Evalúa como true si la expresión de string a la izquierda se encuentra en cualquier parte de la expresión de string a la derecha.

endsWith

Se evalúa como true si la expresión de cadena de la izquierda termina con la expresión de cadena de la derecha. Es similar a contains, pero solo coincide si la expresión de cadena de la izquierda se encuentra al final de la expresión de cadena de la derecha.

like

Se evalúa como true si la expresión de cadena de la izquierda coincide con la expresión de cadena comodín de la derecha. Una expresión de cadena comodín es una cadena que utiliza caracteres normales con dos caracteres comodín especiales:

  • El comodín * coincide con cero o más de cualquier carácter

  • El comodín ? coincide con cualquier carácter.

Por ejemplo, la cadena comodín "d?g" coincide con "perro", "dig" y "dug", pero no con "ding", "dg" o "un perro".

==, =

Se evalúa como true si la cadena de la izquierda es lexicográficamente igual a la cadena de la derecha.

!=, <>

Se evalúa como true si la cadena de la izquierda no es lexicográficamente igual a la cadena de la derecha.

Ejemplo

Utilizamos los operadores de cadena del motor de consulta para encontrar proyectos con un nombre que comience con la letra 'e' y proyectos con nombres que contengan 'ie':

// Use [c] for case-insensitivity.
NSLog(@"Projects that start with 'e': %lu",
[[projects objectsWhere:@"name BEGINSWITH[c] 'e'"] count]);
NSLog(@"Projects that contain 'ie': %lu",
[[projects objectsWhere:@"name CONTAINS 'ie'"] count]);
// Use [c] for case-insensitivity.
let startWithE = projects.filter("name BEGINSWITH[c] 'e'")
print("Projects that start with 'e': \(startWithE.count)")
let containIe = projects.filter("name CONTAINS 'ie'")
print("Projects that contain 'ie': \(containIe.count)")
// [d] for diacritic insensitivty: contains 'e', 'E', 'é', etc.
let containElike = projects.filter("name CONTAINS[cd] 'e'")
print("Projects that contain 'e', 'E', 'é', etc.: \(containElike.count)")

Nota

La ordenación de cadenas y las consultas sin distinción entre mayúsculas y minúsculas solo se admiten para los conjuntos de caracteres en 'Latin Basic', 'Latin Supplement', 'Latin Extended A' y 'Latin Extended B' (UTF-8 rango 0-591).

Nuevo en la versión 10.47.0.

Puede realizar una consulta geoespacial utilizando el operador IN con una de las formas proporcionadas por el SDK:

  • GeoCircle

  • GeoBox

  • GeoPolygon

Este operador evalúa a true si:

  • Un objeto tiene una "forma" de datos geoespaciales que contiene una propiedad String con el valor de Punto y un List que contiene un par de longitud/latitud.

  • La longitud/latitud del objeto persistente cae dentro de la forma de consulta geoespacial.

let filterArguments = NSMutableArray()
filterArguments.add(largeBox)
let companiesInLargeBox = realm.objects(Geospatial_Company.self)
.filter(NSPredicate(format: "location IN %@", argumentArray: filterArguments as? [Any]))
print("Number of companies in large box: \(companiesInLargeBox.count)")

Para obtener más información sobre cómo consultar datos geoespaciales, consulte Consultar datos geoespaciales.

Se puede aplicar un operador de agregación a una propiedad de colección de un objeto Realm. Los operadores de agregación recorren una colección y la reducen a un único valor.

Operador
Descripción
@avg

Se evalúa como el valor promedio de una propiedad numérica dada en una colección.

@count

Evalúa el número de objetos en la colección dada. Actualmente, esto solo se admite en colecciones con relaciones de varios a varios, no en listas de primitivas. Para usar @count en una lista de primitivas, considere encapsular las primitivas en un objeto Realm.

@max

Se evalúa como el valor más alto de una propiedad numérica dada en una colección.

@min

Se evalúa como el valor más bajo de una propiedad numérica dada en una colección.

@sum

Se evalúa como la suma de una propiedad numérica dada en una colección.

Ejemplo

Creamos un par de filtros para mostrar diferentes facetas de los datos:

  • Proyectos con prioridad de tareas promedio superior a 5.

  • Proyectos de larga duración.

NSLog(@"Projects with average tasks priority above 5: %lu",
[[projects objectsWhere:@"tasks.@avg.priority > 5"] count]);
NSLog(@"Projects where all tasks are lower priority: %lu",
[[projects objectsWhere:@"tasks.@max.priority < 5"] count]);
NSLog(@"Projects where all tasks are high priority: %lu",
[[projects objectsWhere:@"tasks.@min.priority > 5"] count]);
NSLog(@"Projects with more than 5 tasks: %lu",
[[projects objectsWhere:@"tasks.@count > 5"] count]);
NSLog(@"Long running projects: %lu",
[[projects objectsWhere:@"tasks.@sum.progressMinutes > 100"] count]);
let averageTaskPriorityAbove5 = projects.filter("tasks.@avg.priority > 5")
print("Projects with average task priority above 5: \(averageTaskPriorityAbove5.count)")
let allTasksLowerPriority = projects.filter("tasks.@max.priority < 5")
print("Projects where all tasks are lower priority: \(allTasksLowerPriority.count)")
let allTasksHighPriority = projects.filter("tasks.@min.priority > 5")
print("Projects where all tasks are high priority: \(allTasksHighPriority.count)")
let moreThan5Tasks = projects.filter("tasks.@count > 5")
print("Projects with more than 5 tasks: \(moreThan5Tasks.count)")
let longRunningProjects = projects.filter("tasks.@sum.progressMinutes > 100")
print("Long running projects: \(longRunningProjects.count)")

Un operador de conjunto utiliza reglas específicas para determinar si se debe pasar cada objeto de colección de entrada a la colección de salida aplicando un predicado determinado a cada elemento de una propiedad de lista determinada del objeto.

Operador
Descripción

ALL

Devuelve objetos donde el predicado evalúa como true para todos los objetos de la colección.

ANY, SOME

Devuelve objetos donde el predicado evalúa a true para cualquier objeto de la colección.

NONE

Devuelve objetos donde el predicado se evalúa como falso para todos los objetos de la colección.

Ejemplo

Utilizamos los operadores de conjunto del motor de consulta para encontrar:

  • Proyectos sin tareas completadas.

  • Proyectos con tareas de máxima prioridad.

NSLog(@"Projects with no complete tasks: %lu",
[[projects objectsWhere:@"NONE tasks.isComplete == true"] count]);
NSLog(@"Projects with any top priority tasks: %lu",
[[projects objectsWhere:@"ANY tasks.priority == 10"] count]);
let noCompleteTasks = projects.filter("NONE tasks.isComplete == true")
print("Projects with no complete tasks: \(noCompleteTasks.count)")
let anyTopPriorityTasks = projects.filter("ANY tasks.priority == 10")
print("Projects with any top priority tasks: \(anyTopPriorityTasks.count)")

Puede iterar a través de una propiedad de colección con otra consulta utilizando la función de predicado SUBQUERY(). SUBQUERY() tiene la siguiente firma:

SUBQUERY(<collection>, <variableName>, <predicate>)
  • collection: el nombre de la propiedad de lista a recorrer

  • variableName: un nombre de variable del elemento actual a utilizar en la subconsulta

  • predicate: una cadena que contiene el predicado de la subconsulta. Puede usar el nombre de variable especificado por variableName para referirse al elemento iterado actualmente.

Ejemplo

Al ejecutar el siguiente filtro en una colección projects, se devuelven proyectos con tareas que no han sido completadas por un usuario llamado Alex.

NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"SUBQUERY(tasks, $task, $task.isComplete == %@ AND $task.assignee == %@).@count > 0",
@NO,
@"Alex"];
NSLog(@"Projects with incomplete tasks assigned to Alex: %lu",
[[projects objectsWithPredicate:predicate] count]);
let predicate = NSPredicate(
format: "SUBQUERY(tasks, $task, $task.isComplete == false AND $task.assignee == %@).@count > 0", "Alex")
print("Projects with incomplete tasks assigned to Alex: \(projects.filter(predicate).count)")

Volver

Enhebrado