Filtrar dados — Swift SDK
Nesta página
- Visão geral
- Sobre os exemplos nesta página
- API de query rápida do Realm
- Operadores
- Operadores de comparação
- Collections
- Operadores lógicos
- Operadores de strings
- Operadores geoespaciais
- Operadores agregados
- Definir operadores
- Subqueries
- Queries NSPredicate
- Expressões
- Notação de ponto
- Substituições
- Operadores
- Operadores de comparação
- Operadores lógicos
- Operadores de strings
- Operadores geoespaciais
- Operadores agregados
- Definir operadores
- Subqueries
Visão geral
Para filtrar dados em seu domínio, utilize o mecanismo de query do Realm.
Novo na versão 10.19.0:: API de query rápida do Realm
A API Realm Swift Query oferece uma maneira idiomática para os desenvolvedores do Swift consultarem dados. Use a sintaxe no estilo Swift para consultar um Realm com os benefícios do preenchimento automático e da segurança de tipos. A API Realm Swift Query não substitui a API de Consulta NSPredicate em versões mais recentes do SDK; em vez disso, você pode usar qualquer uma.
Para versões do SDK anteriores a 10.19.0 ou para desenvolvedores Objective-C, o query do Realm oferece suporte ao NSPredicate Query.
Sobre os exemplos nesta página
Os exemplos nesta página usam um conjunto de dados simples para uma aplicação de lista de tarefas. Os dois tipos de objetos do Realm são Project
e Task
. Uma Task
tem um nome, o nome do responsável e um sinalizador finalizado. Há também um número arbitrário de prioridade -- maior é mais importante -- e o número de minutos gastos trabalhando nisso. Por fim, uma Task
pode ter uma ou mais de string labels
e um ou mais ratings
inteiras.
Um Project
tem zero ou mais Tasks
.
Consulte o esquema para estas duas classes, Project
e Task
, abaixo:
// 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 { var name = "" var isComplete = false var assignee: String? var priority = 0 var progressMinutes = 0 var labels: MutableSet<String> var ratings: MutableSet<Int> } class Project: Object { var name = "" var tasks: List<Task> }
Você pode configurar o domínio para estes exemplos com o seguinte 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)
API de query rápida do Realm
Novidades na versão 10.19.0: Para versões do SDK anteriores à 10.19.0, use a query NSPredicate API.
Você pode construir um filtro com sintaxe de estilo Swift utilizando a .where
API de query Realm Swift:
let realmSwiftQuery = projects.where { ($0.tasks.progressMinutes > 1) && ($0.tasks.assignee == "Ali") }
Essa API de query constrói um NSPredicate para realizar a query. Ele oferece aos desenvolvedores uma API idiomática de tipo seguro para uso direto e abstrai a construção do NSPredicate.
A API .where
recebe uma chamada de resposta avaliada como verdadeiro ou falso. A chamada de resposta recebe uma instância do tipo que está sendo consultado e você pode aproveitar o compilador para verificar estaticamente se está criando queries válidas que referenciam propriedades válidas.
Nos exemplos nesta página, usamos a abreviação $0
para fazer referência a variável passada para a chamada de resposta.
Operadores
Há vários tipos de operadores disponíveis para consultar uma collection do Realm. As queries funcionam avaliando uma expressão de operador para cada objeto na collection que está sendo consultada. Se a expressão resolver para true
, o banco de dados do Realm incluirá o objeto na collection de resultados.
Operadores de comparação
Você pode usar os operadores de comparação do Swift com a API Realm Swift Query (==
, !=
, >
, >=
, <
, <=
).
Exemplo
O exemplo a seguir usa operadores de comparação do mecanismo de consulta para:
Encontre tarefas de alta prioridade comparando o valor da propriedade
priority
com um número limite, acima do qual a prioridade pode ser considerada alta.Encontre tarefas de longa execução verificando se a propriedade
progressMinutes
está igual ou superior a um determinado valor.Encontre tarefas não atribuídas encontrando tarefas onde a propriedade
assignee
é igual anull
.
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)")
Collections
Você pode consultar valores dentro de uma collection utilizando os operadores de .contains
. Você pode pesquisar valores individuais por elemento ou pesquisar dentro de um intervalo.
Operador | Descrição |
---|---|
.in(_ collection:) | Avalia como true se a propriedade a que a expressão faz referência contiver um elemento na array disponibilizada. |
.contains(_ element:) | Equivalente ao operador IN . Avalia como true se a propriedade a que a expressão faz referência contiver o valor. |
.contains(_ range:) | Equivalente ao operador BETWEEN . Avalia como true se a propriedade referenciada pela expressão contém um valor que está dentro do intervalo. |
.containsAny(in: ) | Equivalente ao operador IN combinado com o operador ANY . Avalia como true se algum elemento contido na matriz fornecida estiver presente na coleção. |
Exemplo
Encontre tarefas em que a propriedade da collection MutableSet
labels
contém uma "solução rápida".Encontre tarefas em que propriedade
progressMinutes
está dentro de uma determinada faixa 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)")
Encontre tarefas em que a propriedade da collection MutableSet labels
contém qualquer um dos elementos na array disponibilizada: "solução rápida" ou "bug".
let quickWinOrBugTasks = tasks.where { $0.labels.containsAny(in: ["quick win", "bug"]) } print("Tasks labeled 'quick win' or 'bug': \(quickWinOrBugTasks.count)")
Novidade na versão 10.23.0:: O operador IN
A API Realm Swift Query agora suporta o operador IN
. Avalia como true
se a propriedade a que a expressão faz referência contiver o valor.
Exemplo
Encontre tarefas atribuídas a membros específicos da equipe Ali ou Jamie verificando se a propriedade assignee
está em uma lista de nomes.
let taskAssigneeInAliOrJamie = tasks.where { let assigneeNames = ["Ali", "Jamie"] return $0.assignee.in(assigneeNames) } print("Tasks IN Ali or Jamie: \(taskAssigneeInAliOrJamie.count)")
Operadores lógicos
É possível fazer queries compostas usando os operadores lógicos do Swift (&&
, !
, ||
).
Exemplo
Podemos usar os operadores lógicos da linguagem de consulta para encontrar todas as tarefas concluídas de Ali. Ou seja, encontramos todas as tarefas em que o valor da propriedade assignee
é igual a "Ali" E o valor da propriedade isComplete
é true
:
let aliComplete = tasks.where { ($0.assignee == "Ali") && ($0.isComplete == true) } print("Ali's complete tasks: \(aliComplete.count)")
Operadores de strings
Você pode comparar valores de string utilizando esses operadores de string. Curingas do tipo Regex permitem mais flexibilidade na pesquisa.
Observação
Você pode usar as seguintes opções com operadores de string:
.caseInsensitive
para insensibilidade a maiúsculas e minúsculas.$0.name.contains("f", options: .caseInsensitive) .diacriticInsensitive
para insensibilidade diacrítica: o Realm trata caracteres especiais como o caractere base (por exemplo:é
->e
).$0.name.contains("e", options: .diacriticInsensitive)
Operador | Descrição |
---|---|
.starts(with value: String) | Avalia como true se a collection contiver um elemento cujo valor começa com o valor da string especificado. |
.contains(_ value: String) | Avaliado como true se a expressão de string à esquerda for encontrada em qualquer lugar na expressão de string à direita. |
.ends(with value: String) | Avalia como true se a collection contiver um elemento cujo valor termina com o valor da string especificado. |
.like(_ value: String) | Avalia como
Por exemplo, a cadeia curinga "d?g" corresponde a "dog", "dig" e "cavg", mas não "ding", "dg" ou "a dog". |
== | Avalia como true se a string esquerda for lexicograficamente igual à string direita. |
!= | Avalia para true se a string esquerda não for lexicograficamente igual à string direita. |
Exemplo
O exemplo a seguir utiliza os operadores de string do mecanismo de query para localizar:
Projetos com um nome começando com a letra 'e'
Projetos com nomes que contêm "ou"
Projetos com uma propriedade
assignee
cujo valor é semelhante aAl?x
Projetos que contêm caracteres semelhantes aos eletrônicos com insensibilidade 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)")
Observação
Somente é permitido classificar strings e consultas sem diferenciação de maiúsculas e minúsculas para conjuntos de caracteres em 'Latin Basic', 'Latin Supplement', 'Latin Extended A' e 'Latin Extended B' (UTF-8 faixa 0-591).
Operadores geoespaciais
Novidades na versão 10.47.0.
Use o operador geoWithin
para fazer query de dados geoespaciais com uma das formas fornecidas pelo SDK:
GeoCircle
GeoBox
GeoPolygon
Este operador avalia para true
se:
Um objeto tem um "forma" de dados geoespaciais contendo uma propriedade
String
com o valor de Ponto e umList
contendo um par longitude/latitude.A longitude/latitude do objeto persistente cai dentro da forma de query geoespacial.
let companiesInSmallCircle = realm.objects(Geospatial_Company.self).where { $0.location.geoWithin(smallCircle!) } print("Number of companies in small circle: \(companiesInSmallCircle.count)")
Para obter mais informações sobre a query de dados geoespaciais, consulte Fazer query de dados geoespaciais.
Operadores agregados
Você pode aplicar um operador agregado a uma propriedade de collection de um objeto Realm. Operadores agregados atravessam uma collection e a reduzem para um único valor.
Operador | Descrição |
---|---|
.avg | Avalia conforme o valor médio de uma determinada propriedade numérica em uma coleção. |
.count | Avalia o número de objetos na coleção fornecida. Atualmente, isso só é suportado em coleção de relacionamentos para muitos e não em listas de primitivas. Para utilizar .count em uma lista de primitivas, considere envolver as primitivas em um Objeto de Realm. |
.max | Avalia conforme o valor mais alto de uma determinada propriedade numérica em uma collection. |
.min | Avalia conforme o valor mais baixo de uma determinada propriedade numérica em uma collection. |
.sum | Avalia conforme a soma de uma determinada propriedade numérica em uma collection. |
Exemplo
Criamos alguns filtros para mostrar facetas diferentes dos dados:
Projetos com prioridade média de tarefas acima de 5.
Projetos que contêm apenas tarefas de baixa prioridade abaixo de 5.
Projetos em que todas as tarefas são de alta prioridade acima de 5.
Projetos que contêm mais de 5 tarefas.
Projetos de longa duração.
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)")
Definir operadores
Um operador de conjunto usa regras específicas para determinar se deve passar cada objeto da collection de entrada para a collection de saída aplicando uma determinada expressão de query a cada elemento de uma determinada propriedade de lista do objeto.
Exemplo
A execução das queries a seguir nas collections projects
retorna:
Projetos em que um conjunto de strings
labels
contém qualquer "solução rápida" ou "bug".Projetos em que qualquer elemento em um conjunto de
ratings
de números inteiros é maior 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)")
Subqueries
Você pode iterar uma propriedade de collection com outra query usando uma subquery. Para formar uma subquery, você deve encapsular a expressão entre parênteses e segui-la imediatamente com o agregador .count
.
(<query>).count > n
Se a expressão não produzir uma subquery válida, será gerada uma exceção no tempo de execução.
Exemplo
A execução da query a seguir em uma collection projects
retorna projetos com tarefas que não foram concluídas por um usuário chamado 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)")
Queries NSPredicate
Você pode construir um filtro com NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"progressMinutes > %@ AND name == %@", @1, @"Ali"];
let predicate = NSPredicate(format: "progressMinutes > 1 AND name == %@", "Ali")
Expressões
Os filtros consistem em expressões em um NSPredicate. Uma expressão consiste em uma das seguintes opções:
O nome (keypath) de uma propriedade do objeto que está sendo avaliado.
Um operador e até duas expressões de argumentos.
Um valor, como uma string (
'hello'
) ou um número (5
).
Notação de ponto
Ao se referir a uma propriedade de objeto, é possível usar a notação de ponto para se referir às propriedades filhas desse objeto. Você pode até mesmo fazer referência às propriedades de objetos embarcados e relacionamentos com notação de ponto.
Por exemplo, considere uma query um objeto com uma propriedade workplace
que se refere a um objeto de local de trabalho. O objeto do local de trabalho tem uma propriedade de objeto embarcado, address
. Você pode encadear notação de ponto para se referir à propriedade de código postal desse endereço:
workplace.address.zipcode == 10012
Substituições
Você pode utilizar as seguintes substituições em suas strings de formato de predicado:
%@
para especificar valores%K
para especificar keypaths
[NSPredicate predicateWithFormat:@"%K > %@ AND %K == %@", @"progressMinutes", @1, @"name", @"Ali"];
NSPredicate(format: "%K > %@ AND %K == %@", "progressMinutes", NSNumber(1), "name", "Ali")
Operadores
Há vários tipos de operadores disponíveis para filtrar uma collection do Realm. Os filtros funcionam avaliando uma expressão de operador para cada objeto na collection que está sendo filtrada. Se a expressão resolver para true
, o banco de dados do Realm incluirá o objeto na collection de resultados.
Operadores de comparação
A operação mais direta em uma pesquisa é a comparação de valores.
Importante
Os tipos devem corresponder
O tipo em ambos os lados do operador deve ser equivalente. Por exemplo, comparar um ObjectId com string resultará em uma falha de pré-condição com uma mensagem como:
"Expected object of type object id for property 'id' on object of type 'User', but received: 11223344556677889900aabb (Invalid value)"
Você pode comparar qualquer tipo numérico com qualquer outro tipo numérico.
Operador | Descrição |
---|---|
between | Avalia como true se a expressão numérica ou de data à esquerda estiver entre ou igual ao intervalo à direita. Para datas, isso é avaliado como true se a data à esquerda estiver dentro do intervalo de datas à direita. |
== , = | Avalia para true se a expressão do lado esquerdo é igual à expressão do lado direito. |
> | Avalia como true se a expressão numérica ou de data do lado esquerdo é maior que a expressão numérica ou de data do lado direito. Com datas, avalia como true se a data do lado esquerdo é posterior à data do lado direito. |
>= | Avalia como true se a expressão numérica ou de data do lado esquerdo é maior ou igual à expressão numérica ou de data do lado direito. Com datas, avalia como true se a data do lado esquerdo é posterior ou igual à data do lado direito. |
in | Avalia como true se a expressão da esquerda estiver na lista ou string da direita. |
< | Avalia como true se a expressão numérica ou de data do lado esquerdo é menor que a expressão numérica ou de data do lado direito. Com datas, avalia como true se a data do lado esquerdo é anterior à data do lado direito. |
<= | Avalia como true se a expressão numérica à esquerda for menor ou igual à expressão numérica à direita. Com datas, avalia como true se a data do lado esquerdo é anterior ou igual à data do lado direito. |
!= , <> | Avalia como true se a expressão do lado esquerdo não é igual à expressão do lado direito. |
Exemplo
O exemplo a seguir usa operadores de comparação do mecanismo de consulta para:
Encontre tarefas de alta prioridade comparando o valor da propriedade
priority
com um número limite, acima do qual a prioridade pode ser considerada alta.Encontre tarefas de longa execução verificando se a propriedade
progressMinutes
está igual ou superior a um determinado valor.Encontre tarefas não atribuídas encontrando tarefas onde a propriedade
assignee
é igual anull
.Encontre tarefas atribuídas a membros específicos da equipe Ali ou Jamie verificando se a propriedade
assignee
está em uma lista de nomes.
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)")
Operadores lógicos
Você pode fazer predicados compostos usando operadores lógicos.
Operador | Descrição |
---|---|
and && | Avalia para true se as expressões da esquerda e da direita forem true . |
not ! | Nega o resultado da expressão fornecida. |
or || | Avalia como true se qualquer uma das expressões retornar true . |
Exemplo
Podemos usar os operadores lógicos da linguagem de consulta para encontrar todas as tarefas concluídas de Ali. Ou seja, encontramos todas as tarefas em que o valor da propriedade assignee
é igual a "Ali" E o valor da propriedade isComplete
é 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)")
Operadores de strings
Você pode comparar valores de string utilizando esses operadores de string. Curingas do tipo Regex permitem mais flexibilidade na pesquisa.
Observação
Você pode usar os seguintes modificadores com os operadores de string:
[c]
para insensibilidade a maiúsculas e minúsculas.[NSPredicate predicateWithFormat: @"name CONTAINS[c] 'f'"] NSPredicate(format: "name CONTAINS[c] 'f'") [d]
para insensibilidade diacrítica: o Realm trata caracteres especiais como o caractere base (por exemplo:é
->e
).[NSPredicate predicateWithFormat: @"name CONTAINS[d] 'e'"] NSPredicate(format: "name CONTAINS[d] 'e'")
Operador | Descrição |
---|---|
beginsWith | Avalia para true se a expressão de string à esquerda começar com a expressão de string à direita. Isso é semelhante a contains , mas só corresponde se a expressão de cadeia de caracteres à direita for encontrada no início da expressão de cadeia de caracteres à esquerda. |
contains , in | Avaliado como true se a expressão de string à esquerda for encontrada em qualquer lugar na expressão de string à direita. |
endsWith | Avalia como true se a expressão de string à esquerda terminar com a expressão de string à direita. Isso é semelhante ao contains , mas só corresponde se a expressão de cadeia de caracteres à esquerda for encontrada no final da expressão de cadeia de caracteres à direita. |
like | Avalia como
Por exemplo, a cadeia curinga "d?g" corresponde a "dog", "dig" e "cavg", mas não "ding", "dg" ou "a dog". |
== , = | Avalia como true se a string esquerda for lexicograficamente igual à string direita. |
!= , <> | Avalia para true se a string esquerda não for lexicograficamente igual à string direita. |
Exemplo
Usamos os operadores de cadeia de caracteres do mecanismo de consulta para encontrar projetos com um nome que comece com a letra "e" e projetos com nomes que contenham "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)")
Observação
Somente é permitido classificar strings e consultas sem diferenciação de maiúsculas e minúsculas para conjuntos de caracteres em 'Latin Basic', 'Latin Supplement', 'Latin Extended A' e 'Latin Extended B' (UTF-8 faixa 0-591).
Operadores geoespaciais
Novidades na versão 10.47.0.
Você pode executar uma query geoespacial usando o operador IN
com uma das formas fornecidas do SDK:
GeoCircle
GeoBox
GeoPolygon
Este operador avalia para true
se:
Um objeto tem um "forma" de dados geoespaciais contendo uma propriedade
String
com o valor de Ponto e umList
contendo um par longitude/latitude.A longitude/latitude do objeto persistente cai dentro da forma de query 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 obter mais informações sobre a query de dados geoespaciais, consulte Fazer query de dados geoespaciais.
Operadores agregados
Você pode aplicar um operador agregado a uma propriedade de collection de um objeto Realm. Operadores agregados atravessam uma collection e a reduzem para um único valor.
Operador | Descrição |
---|---|
@avg | Avalia conforme o valor médio de uma determinada propriedade numérica em uma coleção. |
@count | Avalia o número de objetos na coleção fornecida. Atualmente, isso só é suportado em coleção de relacionamentos para muitos e não em listas de primitivas. Para utilizar @count em uma lista de primitivas, considere envolver as primitivas em um Objeto de Realm. |
@max | Avalia conforme o valor mais alto de uma determinada propriedade numérica em uma collection. |
@min | Avalia conforme o valor mais baixo de uma determinada propriedade numérica em uma collection. |
@sum | Avalia conforme a soma de uma determinada propriedade numérica em uma collection. |
Exemplo
Criamos alguns filtros para mostrar facetas diferentes dos dados:
Projetos com prioridade média de tarefas acima de 5.
Projetos de longa duração.
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)")
Definir operadores
Um operador de conjunto usa regras específicas para determinar se deve passar cada objeto de collection de entrada para a collection de saída, aplicando um determinado predicado a cada elemento de uma determinada propriedade de lista do objeto.
Operador | Descrição |
---|---|
ALL | Retorna objetos onde o predicado avalia para true para todos os objetos na coleção. |
ANY , SOME | Retorna objetos onde o predicado avalia para true para quaisquer objetos na coleção. |
NONE | Retorna objetos onde o predicado avalia como falso para todos os objetos na coleção. |
Exemplo
Usamos os operadores de conjunto do mecanismo de query para encontrar:
Projetos sem tarefas concluídas.
Projetos com quaisquer tarefas de alta prioridade.
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)")
Subqueries
Você pode iterar por meio de uma propriedade de collection com outra query usando a função de predicado SUBQUERY()
. SUBQUERY()
tem a seguinte assinatura:
SUBQUERY(<collection>, <variableName>, <predicate>)
collection
: o nome da propriedade da lista pela qual fazer a iteraçãovariableName
: um nome de variável do elemento atual a ser usado na subquerypredicate
: uma string que contém o predicado da subquery. Você pode usar o nome da variável especificado porvariableName
para fazer referência ao elemento atualmente iterado.
Exemplo
A execução do filtro a seguir em uma collection projects
retorna projetos com tarefas que não foram concluídas por um usuário chamado 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)")