Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
CRUD

Filter Data - Java SDK

Para filtrar datos en tu entorno, utiliza el motor de query de Realm.

There are two ways to access the query engine with the Java SDK:

  • Fluent interface

  • Lenguaje de consulta de reino

El SDK de Java utiliza una interfaz Fluent para construir consultas de múltiples cláusulas que se pasan al motor de consultas.

See RealmQuery API for a complete list of available methods.

Hay 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 como trueLa base de datos Realm incluye el objeto en la colección de resultados.

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.

The examples in this section 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:

ProjectTask.java
import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
public class ProjectTask extends RealmObject {
@PrimaryKey
public ObjectId _id;
@Required
public String name;
public String assignee;
public int progressMinutes;
public boolean isComplete;
public int priority;
@Required
public String _partition;
}
Project.java
import org.bson.types.ObjectId;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
public class Project extends RealmObject {
@PrimaryKey
public ObjectId _id;
@Required
public String name;
public RealmList<ProjectTask> tasks = new RealmList<>();
}
ProjectTask.kt
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import org.bson.types.ObjectId
open class ProjectTask(
@PrimaryKey
var _id: ObjectId = ObjectId(),
@Required
var name: String = "",
var assignee: String? = null,
var progressMinutes: Int = 0,
var isComplete: Boolean = false,
var priority: Int = 0,
var _partition: String = ""
): RealmObject()
Project.kt
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import org.bson.types.ObjectId
open class Project(
@PrimaryKey
var _id: ObjectId = ObjectId(),
@Required
var name: String = "",
var tasks: RealmList<ProjectTask> = RealmList(),
): RealmObject()

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

Operador
Descripción

between

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.

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.

in

Evaluates to true if the left-hand expression is in the right-hand list.

lessThan

Devuelve true si la expresión numérica o de fecha de la izquierda es menor que la expresión numérica o de fecha de la derecha. Para fechas, esto da como resultado true si la fecha de la izquierda es anterior a la fecha de la derecha.

lessThanOrEqualTo

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.

notEqualTo

Evaluates to true if the left-hand expression is not equal to the right-hand expression.

Ejemplo

The following example uses the query engine's comparison operators to:

  • 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.

  • 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.

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
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", new String[]{"Ali", "Jamie"}).count());
val tasksQuery = realm.where(ProjectTask::class.java)
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.

Operador
Descripción
and

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

not

Negates the result of the given expression.

or

Evaluates to true if either expression returns true.

Ejemplo

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:

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
Log.i("EXAMPLE", "Ali has completed " +
tasksQuery.equalTo("assignee", "Ali").and().equalTo("isComplete", true).findAll().size() +
" tasks.");
val tasksQuery = realm.where(ProjectTask::class.java)
Log.i("EXAMPLE", "Ali has completed " +
tasksQuery.equalTo("assignee", "Ali").and()
.equalTo("isComplete", true).findAll().size + " tasks.")

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

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 izquierda se encuentra al principio de la expresión de cadena de la derecha.

contains

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

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.

Ejemplo

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':

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

Nota

Limitaciones de caracteres que no distinguen entre mayúsculas y minúsculas

Los operadores de strings que no distinguen entre mayúsculas y minúsculas solo soportan los conjuntos de caracteres Latin Basic, Latin Supplement, Latin Extended A y Latin Extended B (UTF-8 range 0–591). Establecer la indicación de insensibilidad a mayúsculas y minúsculas en las queries al usar equalTo, notEqualTo, contains, endsWith, beginsWith o like solo funciona con caracteres de la localización inglesa.

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
average

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

count

Evalúa al número de objetos en la colección dada.

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.

Ejemplo

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

  • Projects with average tasks priority above 5.

  • Long running projects.

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
/*
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"));
val tasksQuery = realm.where(ProjectTask::class.java)
/*
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"))

The examples in this section use two Realm object types: Teacher and Student.

See the schema for these two classes below:

Teacher.java
import io.realm.RealmList;
import io.realm.RealmObject;
public class Teacher extends RealmObject {
private String name;
private Integer numYearsTeaching;
private String subject;
private RealmList<Student> students;
public Teacher() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getNumYearsTeaching() { return numYearsTeaching; }
public void setNumYearsTeaching(Integer numYearsTeaching) { this.numYearsTeaching = numYearsTeaching; }
public String getSubject() { return subject; }
public void setSubject(String subject) { this.subject = subject; }
public RealmList<Student> getStudents() { return students; }
public void setStudents(RealmList<Student> students) { this.students = students; }
}
Student.java
import io.realm.RealmObject;
import io.realm.RealmResults;
import io.realm.annotations.LinkingObjects;
public class Student extends RealmObject {
private String name;
private Integer year;
@LinkingObjects("students")
private final RealmResults<Teacher> teacher = null;
public Student() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getYear() { return year; }
public void setYear(Integer year) { this.year = year; }
public RealmResults<Teacher> getTeacher() { return teacher; }
}
Profesor.kt
import io.realm.RealmList
import io.realm.RealmObject
open class Teacher : RealmObject() {
var name: String? = null
var numYearsTeaching: Int? = null
var subject: String? = null
var students: RealmList<Student>? = null
}
Student.kt
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
open class Student : RealmObject() {
var name: String? = null
var year: Int? = null
@LinkingObjects("students")
val teacher: RealmResults<Teacher>? = null
}

Puedes compilar filtros utilizando los métodos operadores de la interfaz fluida que expone la clase RealmQuery:

// Build the query looking at all teachers:
RealmQuery<Teacher> query = realm.where(Teacher.class);
// Add query conditions:
query.equalTo("name", "Ms. Langtree");
query.or().equalTo("name", "Mrs. Jacobs");
// Execute the query:
RealmResults<Teacher> result1 = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<Teacher> result2 = realm.where(Teacher.class)
.equalTo("name", "Ms. Langtree")
.or()
.equalTo("name", "Mrs. Jacobs")
.findAll();
// Build the query looking at all teachers:
val query = realm.where(Teacher::class.java)
// Add query conditions:
query.equalTo("name", "Ms. Langtree")
query.or().equalTo("name", "Mrs. Jacobs")
// Execute the query:
val result1 = query.findAll()
// Or alternatively do the same all at once (the "Fluent interface"):
val result2 = realm.where(Teacher::class.java)
.equalTo("name", "Ms. Langtree")
.or()
.equalTo("name", "Mrs. Jacobs")
.findAll()

Esto le proporciona una nueva instancia de la clase RealmResults, que contiene profesores con el nombre "Sra. Langtree" o "Sra. Jacobs".

RealmQuery includes several methods that can execute queries:

  • findAll() se bloquea hasta que encuentra todos los objetos que cumplen las condiciones de consulta

  • findAllAsync() regresa inmediatamente y encuentra todos los objetos que cumplen las condiciones de consulta de forma asincrónica en un hilo en segundo plano.

  • findFirst() blocks until it finds the first object that meets the query conditions

  • findFirstAsync() returns immediately and finds the first object that meets the query conditions asynchronously on a background thread

Queries return a list of references to the matching Realm objects using the RealmResults type.

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

For example, consider a query for all teachers with a student named "Wirt" or "Greg":

// Find all teachers who have students with the names "Wirt" or "Greg"
RealmResults<Teacher> result = realm.where(Teacher.class)
.equalTo("students.name", "Wirt")
.or()
.equalTo("students.name", "Greg")
.findAll();
// Find all teachers who have students with the names "Wirt" or "Greg"
val result = realm.where(Teacher::class.java)
.equalTo("students.name", "Wirt")
.or()
.equalTo("students.name", "Greg")
.findAll()

You can even use dot notation to query inverse relationships:

// Find all students who have teachers with the names "Ms. Langtree" or "Mrs. Jacobs"
RealmResults<Student> result = realm.where(Student.class)
.equalTo("teacher.name", "Ms. Langtree")
.or()
.equalTo("teacher.name", "Mrs. Jacobs")
.findAll();
// Find all students who have teachers with the names "Ms. Langtree" or "Mrs. Jacobs"
val result = realm.where(Student::class.java)
.equalTo("teacher.name", "Ms. Langtree")
.or()
.equalTo("teacher.name", "Mrs. Jacobs")
.findAll()

Importante

Realm applies the distinct(), sort() and limit() methods in the order you specify. Depending on the data set this can alter the query result. Generally, you should apply limit() last to avoid unintended result sets.

Puede definir el orden de los resultados de la consulta utilizando el método sort():

// Find all students in year 7, and sort them by name
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 7)
.sort("name")
.findAll();
// Alternatively, find all students in year 7
RealmResults<Student> unsortedResult = realm.where(Student.class)
.equalTo("year", 7)
.findAll();
// then sort the results set by name
RealmResults<Student> sortedResult = unsortedResult.sort("name");
// Find all students in year 7, and sort them by name
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 7L)
.sort("name")
.findAll()
// Alternatively, find all students in year 7
val unsortedResult: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 7L)
.findAll()
// then sort the results set by name
val sortedResult = unsortedResult.sort("name")

Sorts organize results in ascending order by default. To organize results in descending order, pass Sort.DESCENDING as a second argument. You can resolve sort order ties between identical property values by passing an array of properties instead of a single property: in the event of a tie, Realm sorts the tied objects by subsequent properties in order.

Nota

String Sorting Limitations

Realm uses non-standard sorting for upper and lowercase letters, sorting them together rather than sorting uppercase first. As a result, '- !"#0&()*,./:;?_+<=>123aAbBcC...xXyYzZ is the actual sorting order in Realm. Additionally, sorting strings only supports the Latin Basic, Latin Supplement, Latin Extended A, and Latin Extended B (UTF-8 range 0–591) character sets.

Puede limitar el número de resultados de la consulta a un número máximo específico utilizando el método limit():

// Find all students in year 8, and limit the results collection to 10 items
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 8)
.limit(10)
.findAll();
// Find all students in year 8, and limit the results collection to 10 items
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 8L)
.limit(10)
.findAll()

Las colecciones de resultados limitadas se actualizan automáticamente como cualquier otro resultado de consulta. Por lo tanto, los objetos podrían desaparecer de la colección a medida que cambian los datos subyacentes.

Tip

La paginación no es necesaria para la optimización del dominio

Algunas bases de datos incentivan la paginación de los resultados con límites para evitar leer datos innecesarios del disco o usar demasiada memoria.

Dado que las queries de Realm son perezosas, no es necesario tomar tales medidas. Realm solo carga objetos de los resultados de queries cuando se accede a ellos explícitamente.

Tip

Deleted Notifications in Limited Results

notificaciones de la colección reportan objetos como eliminados cuando desaparecen del conjunto de resultados. Esto no significa necesariamente que se hayan eliminado del realm subyacente, solo que ya no forman parte del resultado de la query.

Puede reducir los resultados de la consulta a valores únicos para un campo o campos determinados utilizando el método distinct():

// Find all students in year 9, and cap the result collection at 10 items
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 9)
.distinct("name")
.findAll();
// Find all students in year 9, and cap the result collection at 10 items
val result: RealmResults<Student> = realm.where<Student>(Student::class.java)
.equalTo("year", 9L)
.distinct("name")
.findAll()

Sólo puedes llamar a distinct() en campos de tipo entero, largo, corto y String; otros tipos de campo lanzarán una excepción. Al igual que con la ordenación, puedes especificar varios campos para resolver empates.

Puede aplicar filtros adicionales a una colección de resultados llamando al método where():

// Find all students in year 9 and resolve the query into a results collection
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 9)
.findAll();
// filter the students results again by teacher name
RealmResults<Student> filteredResults = result.where().equalTo("teacher.name", "Ms. Langtree").findAll();
// Find all students in year 9 and resolve the query into a results collection
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 9L)
.findAll()
// filter the students results again by teacher name
val filteredResults =
result.where().equalTo("teacher.name", "Ms. Langtree").findAll()

El where() método devuelve un RealmQuery que se puede convertir en un RealmResults mediante un find método. Los resultados filtrados solo pueden devolver objetos del mismo tipo que el conjunto de resultados original, pero pueden usar cualquier otro filtro.

New in version 10.4.0.

También puedes consultar realms usando Realm Query Language, un languaje del query basado en texto string para restringir búsqueda al obtener objeto de un realm.

Puedes utilizar RealmQuery.rawPredicate(). Para más información sobre sintaxis, uso y limitaciones, consulta la referencia del Lenguaje de Consulta de Realm.

Realm Query Language can use either the class and property names defined in your Realm Model classes or the internal names defined with @RealmField. You can combine raw predicates with other raw predicates or type-safe predicates created with RealmQuery:

// Build a RealmQuery based on the Student type
RealmQuery<Student> query = realm.where(Student.class);
// Simple query
RealmResults<Student> studentsNamedJane =
query.rawPredicate("name = 'Jane'").findAll();
// Multiple predicates
RealmResults<Student> studentsNamedJaneOrJohn =
query.rawPredicate("name = 'Jane' OR name = 'John'").findAll();
// Collection queries
RealmResults<Student> studentsWithTeachers =
query.rawPredicate("teacher.@count > 0").findAll();
RealmResults<Student> studentsWithSeniorTeachers =
query.rawPredicate("ALL teacher.numYearsTeaching > 5").findAll();
// Sub queries
RealmResults<Student> studentsWithMathTeachersNamedSteven =
query.rawPredicate("SUBQUERY(teacher, $teacher, $teacher.subject = 'Mathematics' AND $teacher.name = 'Mr. Stevens').@count > 0").findAll();
// Sort, Distinct, Limit
RealmResults<Student> students =
query.rawPredicate("teacher.@count > 0 SORT(year ASCENDING) DISTINCT(name) LIMIT(5)").findAll();
// Combine two raw predicates
RealmResults<Student> studentsNamedJaneOrHenry =
query.rawPredicate("name = 'Jane'")
.rawPredicate("name = 'Henry'").findAll();
// Combine raw predicate with type-safe predicate
RealmResults<Student> studentsNamedJaneOrHenryAgain =
query.rawPredicate("name = 'Jane'")
.equalTo("name", "Henry").findAll();
// Build a RealmQuery based on the Student type
val query = realm.where(Student::class.java)
// Simple query
val studentsNamedJane = query.rawPredicate("name = 'Jane'").findAll()
// Multiple predicates
val studentsNamedJaneOrJohn =
query.rawPredicate("name = 'Jane' OR name = 'John'").findAll()
// Collection queries
val studentsWithTeachers =
query.rawPredicate("teacher.@count > 0").findAll()
val studentsWithSeniorTeachers =
query.rawPredicate("ALL teacher.numYearsTeaching > 5").findAll()
// Sub queries
val studentsWithMathTeachersNamedSteven =
query.rawPredicate("SUBQUERY(teacher, \$teacher, \$teacher.subject = 'Mathematics' AND \$teacher.name = 'Mr. Stevens').@count > 0")
.findAll()
// Sort, Distinct, Limit
val students =
query.rawPredicate("teacher.@count > 0 SORT(year ASCENDING) DISTINCT(name) LIMIT(5)")
.findAll()
// Combine two raw predicates
val studentsNamedJaneOrHenry = query.rawPredicate("name = 'Jane'")
.rawPredicate("name = 'Henry'").findAll()
// Combine raw predicate with type-safe predicate
val studentsNamedJaneOrHenryAgain =
query.rawPredicate("name = 'Jane'")
.equalTo("name", "Henry").findAll()

Tip

Realm Query Language Examples

You can also find useful Realm Query Language examples on the following pages:

Volver

Borrar

En esta página