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

CRUD - Leer - SDK de Flutter

You can read back the data that you have stored in the database by finding, filtering, and sorting objects.

Una lectura de la base de datos generalmente consta de los siguientes pasos:

  • Obtenga todos los objetos de un tipo determinado de la base de datos.

  • Opcionalmente, puedes filtrar los resultados.

Las operaciones de consulta devuelven un recopilación de resultadosEstas colecciones están activas, lo que significa que siempre contienen los últimos resultados de la consulta asociada.

Diseñe los patrones de acceso a datos de su aplicación en torno a estas tres características de lectura clave para leer los datos de la manera más eficiente posible.

Results to a query are not copies of your data. Modifying the results of a query modifies the data on disk directly. This memory mapping also means that results are live: that is, they always reflect the current state on disk.

The SDK only runs a query when you actually request the results of that query. This lazy evaluation enables you to write highly performant code for handling large data sets and complex queries. You can chain several filter operations without requiring extra work to process the intermediate state.

One benefit of the SDK's object model is that the SDK automatically retains all of an object's relationships as direct references. This enables you to traverse your graph of relationships directly through the results of a query.

Una referencia directa, o puntero, te permite acceder directamente a las propiedades de un objeto relacionado a través de la referencia.

Otras bases de datos suelen copiar objetos del almacenamiento de la base de datos a la memoria de la aplicación cuando necesitas trabajar directamente con ellos. Debido a que los objetos de la aplicación contienen referencias directas, tienes la siguiente opción: copiar el objeto al que se hace referencia en cada referencia directa fuera de la base de datos en caso de que sea necesario, o simplemente copiar la clave externa de cada objeto y hacer query para el objeto con esa clave si se accede a él. Si eliges copiar objetos referenciados a la memoria de la aplicación, puedes usar muchos recursos para objetos a los que nunca se accede, pero si elige solo copiar la clave externa, las búsquedas de objetos referenciados pueden causar que su aplicación se vuelva lenta.

The SDK bypasses all of this using zero-copy live objects. The SDK's object accessors point directly into database storage using memory mapping, so there is no distinction between the objects in the database and the results of your query in application memory. Because of this, you can traverse direct references across an entire database from any query result.

Como resultado de la evaluación perezosa, no necesitas ningún mecanismo especial para limitar los resultados de la query con el SDK. Por ejemplo, si tu query coincide con miles de objetos, pero solo deseas cargar los primeros diez, simplemente accede solo a los primeros diez elementos de la colección de resultados.

Thanks to lazy evaluation, the common task of pagination becomes quite simple. For example, suppose you have a results collection associated with a query that matches thousands of objects in your database. You display one hundred objects per page. To advance to any page, simply access the elements of the results collection starting at the index that corresponds to the target page.

A menos que se indique lo contrario, los ejemplos de esta página utilizan dos tipos de objetos, Person y Team.

@RealmModel()
class _Person {
@PrimaryKey()
late ObjectId id;
late String name;
late List<String> hobbies;
}
@RealmModel()
class _Team {
@PrimaryKey()
late ObjectId id;
late String name;
late List<_Person> crew;
late RealmValue eventLog;
}

Encuentra un objeto por su clave primaria con Realm.find().

final luke = realm.find<Person>(lukePrimaryKey);

Recupera una colección de todos los objetos de un modelo de datos en la base de datos con el Realm.all() método.

final people = realm.all<Person>();

New in version 1.8.0.

Si tu modelo de datos incluye objetos que hacen referencia a otros objetos, puedes consultar la query usando el método getBacklinks().

This method returns a results collection of all objects that link to the given object through a to-one, to-many, or inverse relationship. The following examples use the models defined on the Relationships page.

  • Relación de uno a uno: en este ejemplo, tenemos un Bike modelo de objeto con una relación de uno a uno con un Person objeto.

    We use the getBacklinks() method to find any Bike objects that link to the specified person through the owner property:

    // Persons have a to-one relationship with Bikes
    final person = realm.query<Person>("firstName == 'Anakin'").first;
    // Find all Bikes owned by a Person named 'Anakin'
    final allBikes = person.getBacklinks<Bike>('owner');
  • To-many relationship: In this example, we have a Scooter object model with a to-many relationship with a ScooterShop object.

    We use the getBacklinks() method to find any ScooterShops objects that link to the specified scooter through the scooters list property:

    // Scooters have a to-many relationship with ScooterShops
    final scooters = realm.query<Scooter>("name == 'Scooterbug'").first;
    // Find all ScooterShops with a Scooter named 'Scooterbug'
    final shops = scooters.getBacklinks<ScooterShop>('scooters');
  • Inverse relationship: In this example, we have a Task object model with an inverse relationship with a User object.

    Usamos el método getBacklinks() para encontrar cualquier objeto User que se vincule a las tareas especificadas a través de la propiedad backlinks tasks:

    // Tasks have an inverse relationship to Users
    final inCompleteTasks = realm.query<Task>("isComplete == false");
    // Find all Users who have an incomplete Task
    for (final task in inCompleteTasks) {
    final ownersWithIncompleteTasks = task.getBacklinks<User>('tasks');
    for (final user in ownersWithIncompleteTasks) {
    print("User ${user.username} has incomplete tasks.");
    }
    }

You can query any list of RealmObjects or primitives.

final config = Configuration.local([Person.schema, Team.schema]);
final realm = Realm(config);
final heroes = Team(ObjectId(), 'Millenium Falcon Crew', crew: [
Person(ObjectId(), 'Luke'),
Person(ObjectId(), 'Leia'),
Person(ObjectId(), 'Han'),
Person(ObjectId(), 'Chewbacca')
]);
realm.write(() => realm.add(heroes));
final lukeAndLeia = heroes.crew.query('name BEGINSWITH \$0', ['L']);

Nuevo en la versión 2.0.0.

En Flutter SDK v2.0.0 y versiones posteriores, las propiedades RealmValue pueden contener colecciones (una lista o un map) de datos mixtos. Estas colecciones pueden estar anidadas dentro de otras colecciones y pueden contener otras colecciones de datos mixtos.

Puedes query estas usando la misma sintaxis que usarías para una lista normal o una colección de diccionario. Consulta la documentación de para obtener más información sobre los operadores compatibles y las comparaciones de listas.

For nested collections, you can also use:

  • Notación de corchetes, que proporciona los siguientes operadores del query de colección:

    • [FIRST] y [LAST]: coincide con el primer o último elemento dentro de la colección.

    • [<int>]: coincide con el elemento en el índice específico.

    • [*]: match any element within the collection (this operator assumes a collection type at that path).

    • [SIZE]: match the collection length.

  • El operador @type, que admite los siguientes valores:

    • array y list: coincide con una colección de listas.

    • dictionary y object: coincide con una colección de mapas.

    • collection: coincidir con una lista o una colección de mapas.

realm.write(() {
realm.addAll([
(Team(ObjectId(), 'Janitorial Staff',
eventLog: RealmValue.from({
'1': {
'date': DateTime.utc(5622, 8, 18, 12, 30, 0),
'type': ['work_order', 'maintenance'],
'summary': 'leaking pipes in control room',
'priority': 'high',
},
'2': {
'date': DateTime.utc(5622, 9, 18, 12, 30, 0),
'type': ['maintenance'],
'summary': 'trash compactor jammed',
'priority': 'low',
'comment': 'this is the second time this week'
}
}))),
(Team(ObjectId(), 'IT',
eventLog: RealmValue.from({
'1': {
'date': DateTime.utc(5622, 9, 20, 12, 30, 0),
'type': ['hardware', 'repair'],
'summary': 'lightsaber damage to server room',
'priority': 'high',
}
})))
]);
final teams = realm.all<Team>();
// Use bracket notation to query collection values at the specified path
final teamsWithHighPriorityEvents =
// Check any element at that path with [*]
teams.query("eventLog[*].priority == 'high'");
print(teamsWithHighPriorityEvents.length); // prints `2`
final teamsWithMaintenanceEvents =
// Check for the first element at that path with [FIRST]
teams.query("eventLog[*].type[FIRST] == 'maintenance'");
print(teamsWithMaintenanceEvents.length); // prints `1`
final teamsWithMultipleEvents =
// Check for collection at that path with matching elements
// Note that the order must match unless you use ANY or ALL
teams.query("eventLog[*].type[*] == {'maintenance', 'work_order'}");
print(
teamsWithMultipleEvents.length); // prints `0` because order matters
final teamsWithEventsAsLists =
// Check the collection type with @type
teams.query("eventLog[*].type.@type == 'list'");
print(teamsWithEventsAsLists.length); // prints `2`
});

You can convert a RealmList or RealmSet to an instance of RealmResults using their respective methods:

Estos métodos admiten listas y conjuntos de RealmObjects, así como valores primitivos.

final config = Configuration.local([Person.schema, Team.schema]);
final realm = Realm(config);
final heroes = Team(ObjectId(), 'Millenium Falcon Crew', crew: [
Person(ObjectId(), 'Luke', hobbies: [
'Going to Tashi Station',
'Fixing the Moisture Vaporators'
]),
Person(ObjectId(), 'Leia', hobbies: [
'Going on diplomatic missions',
'Rescuing short stormtroopers'
]),
Person(ObjectId(), 'Han',
hobbies: ['Shooting first', 'Making fast Kessel Runs']),
Person(ObjectId(), 'Chewbacca', hobbies: [
'Fixing the Millenium Falcon',
'Tearing the arms off of droids'
])
]);
realm.write(() => realm.add(heroes));
// Converts the Team object's 'crew' List into a RealmResults<Person>.
final heroesCrewAsResults = heroes.crew.asResults();
final luke = heroesCrewAsResults.query("name == 'Luke'").first;
// Converts Luke's 'hobbies' list into a RealmResults<String>
final lukeHobbiesAsResults = luke.hobbies.asResults();

Filtro de un RealmList para recuperar un segmento específico de objetos con el Realm.query() método. En el argumento del método query(), utiliza el lenguaje de consultas de Realm para realizar un filtrado. El Realm Query Language es un lenguaje de consulta basado en cadenas que puedes utilizar para recuperar objetos de la base de datos.

final team =
realm.query<Team>('name == \$0', ['Millennium Falcon Crew']).first;
final humanCrewMembers = team.crew.query('name != \$0', ['Chewbacca']);

You can use iterable arguments in your filter. For example:

final listOfNames = ['Luke', 'Leia'];
final matchingRealmObjects =
realm.query<Person>('name IN \$0', [listOfNames]);

You can also filter by inverse relationships using the @links.<Type>.<Property> syntax. For example, a filter can match a Task object based on properties of the User object that references it:

// Filter Tasks through the User's backlink property
// using `@links.<ObjectType>.<PropertyName>` syntax
final jarjarsIncompleteTasks = realm.query<Task>(
"ALL @links.User.tasks.username == 'jarjar_binks' AND isComplete == false");
final tasksForHan =
realm.query<Task>("ALL @links.User.tasks.username == 'han'");

Para obtener más información sobre la construcción de consultas, consulta la documentación de referencia del Realm Query Language.

You can use Realm Query Language (RQL) to query on properties that have a Full-Text Search Index (FTS) annotation. To query these properties, use the TEXT predicate in your query.

Exclude results for a word by placing the - character in front of the word. For example, a search for -sheep wool would include all search results for wool excluding those with sheep.

In Flutter SDK version 1.6.0 and later, you can specify prefixes by placing the * character at the end of a word. For example, wo* would include all search results for wool and woven. The Flutter SDK does not currently support suffix searches.

In the following example, we query on the Rug.pattern and Rug.material fields:

// Find rugs with a chevron pattern
final chevronRugs = realm.query<Rug>("pattern TEXT \$0", ["chevron"]);
// Find rugs with a wool material but not sheep wool
final notSheepWoolRugs = realm.query<Rug>("material TEXT \$0", [" -sheep wool"]);
// Find rugs with a material starting with "co-"
final coRugs = realm.query<Rug>("material TEXT \$0", ["co*"]);

Full-Text Search (FTS) indexes support:

  • Boolean match word searches, not searches for relevance.

  • Tokens are diacritics- and case-insensitive.

  • Tokens can only consist of characters from ASCII and the Latin-1 supplement (western languages).

  • All other characters are considered whitespace. Words split by a hyphen (-) like full-text are split into two tokens.

For more information on features of the FTS index, see the API reference for RealmIndexType.

Sort query results using the Realm Query Language SORT() operator in the query() method's argument.

Note that you can't use parameterized queries in RQL SORT() clauses. Instead, use strings or string interpolation.

realm.write(() {
realm.addAll([
Person(ObjectId(), 'Luke'),
Person(ObjectId(), 'Leia'),
Person(ObjectId(), 'Han'),
Person(ObjectId(), 'Chewbacca')
]);
});
final alphabetizedPeople =
realm.query<Person>('TRUEPREDICATE SORT(name ASC)');
for (var person in alphabetizedPeople) {
print(person.name);
}
// prints 'Chewbacca', 'Han', 'Leia', 'Luke'

Limita los resultados de la consulta utilizando el operador LIMIT() del Realm Query Language en el argumento del método query().

Note that you can't use parameterized queries in RQL LIMIT() clauses. Instead, use strings or string interpolation.

realm.write(() {
realm.addAll([
Person(ObjectId(), 'Luke'),
Person(ObjectId(), 'Luke'),
Person(ObjectId(), 'Luke'),
Person(ObjectId(), 'Luke')
]);
});
final limitedPeopleResults =
realm.query<Person>('name == \$0 LIMIT(2)', ['Luke']);
// prints `2`
print(limitedPeopleResults.length);

Volver

Crear