Session: Loading Entities
There are various methods with many overloads that allow users to download documents from a database and convert them to entities. This article will cover the following methods:
Load
The most basic way to load a single entity is to use session's load()
method.
session.load(id, [documentType], [callback]);
Parameters | ||
---|---|---|
id | string | Identifier of a document that will be loaded. |
documentType | function | A class constructor used for reviving the results' entities |
callback | function | error-first callback, returns loaded document |
Return Value | |
---|---|
Promise<object> |
A Promise returning object or null if a document with a given ID does not exist. |
Example
const employee = await session.load("employees/1");
Note
In 4.x RavenDB, only string identifiers are supported. If you are upgrading from 3.x, this is a major change, because in 3.x non-string identifiers are supported.
Load with Includes
When there is a relationship between documents, those documents can be loaded in a single request call using the include()
and load()
methods.
session.include(path);
Parameters | ||
---|---|---|
path | string | Field path in documents in which the server should look for 'referenced' documents. |
Return Value | |
---|---|
object { load() } |
The include() method by itself does not materialize any requests but returns loader containing methods such as load() . |
Example I
We can use this code to also load an employee which made the order.
// loading 'products/1'
// including document found in 'supplier' property
const product = await session
.include("supplier")
.load("products/1");
const supplier = await session.load(product.supplier); // this will *not* make a server call
Load - multiple entities
To load multiple entities at once, use one of the following ways to call load()
.
session.load(idsArray, [documentType], [callback]);
session.load(idsArray, [options], [callback]);
Parameters | ||
---|---|---|
idsArray | string[] | Multiple document identifiers to load |
documentType | function | A class constructor used for reviving the results' entities |
options | string | Options with the following properties |
documentType | function | A class construcor used for reviving the results' entities |
includes | string[] | Field paths in documents in which the server should look for 'referenced' documents. |
callback | function | error-first callback, returns an object mapping document identifiers to object or null if a document with given ID doesn't exist (see Return Value below) |
Return Value | |
---|---|
Promise<{ [id]: object }> |
A Promise resolving to an object mapping document identifiers to object or null if a document with given ID doesn't exist |
const employees = await session.load(
[ "employees/1", "employees/2", "employees/3" ]);
// {
// "employees/1": { ... },
// "employees/2": { ... }
// "employees/3": { ... }
// }
LoadStartingWith
To load multiple entities that contain a common prefix, use the loadStartingWith()
method from the advanced
session operations.
session.advanced.loadStartingWith(idPrefix, [options], [callback]);
Parameters | ||
---|---|---|
idPrefix | string | prefix for which the documents should be returned |
options | string | Options with the following properties |
matches | string | pipe ('|') separated values for which document IDs (after 'idPrefix') should be matched ('?' any single character, '*' any characters) |
start | number | number of documents that should be skipped |
pageSize | number | maximum number of documents that will be retrieved |
exclude | string | pipe ('|') separated values for which document IDs (after 'idPrefix') should not be matched ('?' any single character, '*' any characters) |
skipAfter | string | skip document fetching until given ID is found and return documents after that ID (default: null ) |
documentType | function | A class constructor used for reviving the results' entities |
callback | function | error-first callback, returns an array of entities matching given parameters (see Return Value below) |
Return Value | |
---|---|
Promise<object[]> |
A Promise resolving to an array of entities matching given parameters |
Example I
// return up to 128 entities with Id that starts with 'employees'
const result = await session
.advanced
.loadStartingWith("employees/", {
start: 0,
pageSize: 128
});
Example II
// return up to 128 entities with Id that starts with 'employees/'
// and rest of the key begins with "1" or "2" e.g. employees/10, employees/25
const result = await session
.advanced
.loadStartingWith("employees/", {
matches: "1*|2*",
start: 0,
pageSize: 128
});
Stream
Entities can be streamed from the server using the stream()
method from the advanced
session operations.
// stream query results
session.stream(query, [statsCallback], [callback]);
// stream documents with ID starting with
session.stream(idPrefix, [options], [callback]);
Parameters | ||
---|---|---|
idPrefix | string | prefix for which the documents should be returned |
query | query object | a query obtained from a call to session.query() or session.advanced.rawQuery() |
options | string | Options with the following properties |
startsWith | string | prefix for which documents should be streamed |
matches | string | pipe ('|') separated values for which document IDs should be matched ('?' any single character, '*' any characters) |
start | number | number of documents that should be skipped |
pageSize | number | maximum number of documents that will be retrieved |
skipAfter | string | skip document fetching until a given ID is found and returns documents after that ID (default: null ) |
documentType | function | A class constructor used for reviving the results' entities |
statsCallback | function | callback returning information about the streaming query (amount of results, which index was queried, etc.) |
callback | function | returns a readable stream with query results (same as Return Value result below) |
Return Value | |
---|---|
Promise<Readable> |
A Promise resolving to readable stream with query results |
Example I
Stream documents for a ID prefix:
// stream() returns a Node.js Readable
const stream = await session.advanced.stream("employees/");
stream.on("data", data => {
// Employee { name: 'Anna', id: 'employees/1-A' }
});
stream.on("error", err => {
// handle errors
});
stream.on("end", () => {
// stream ended
});
Example 2
Fetch documents for a ID prefix directly into a writable stream:
const employeesFile = fs.createWriteStream("employees.json");
await session.advanced.loadStartingWithIntoStream("employees/", employeesFile);
Information
Entities loaded using stream()
will be transient (not attached to session).
IsLoaded
To check if an entity is attached to a session, e.g. it has been loaded previously, use the isLoaded
method from the advanced
session operations.
If you try to load a document that does not exist with the load
method, isLoaded
will return true
because that document load has already been attempted.
session.advanced.isLoaded(id);
Parameters | ||
---|---|---|
id | string | Entity ID for which the check should be performed. |
Return Value | |
---|---|
boolean | Indicates if an entity with a given ID is loaded. |
Example
session.advanced.isLoaded("employees/1"); // false
const employee = await session.load("employees/1");
session.advanced.isLoaded("employees/1"); // true
On entities loading, JS classes and the documentType parameter
Type information about the entity and its contents is by default stored in the document metadata. Based on that its types are revived when loaded from the server.
Entity type registration
In order to avoid passing documentType argument every time, you can register the type in the document conventions using the registerEntityType()
method before calling DocumentStore's initialize()
like so:
class Pet {
constructor(name) {
this.name = name;
}
}
class Person {
constructor(name, pet) {
this.name = name;
this.pet = pet;
}
}
documentStore.conventions.registerEntityType(Person);
documentStore.conventions.registerEntityType(Pet);
// ...
documentStore.initialize();
If you fail to do so, entities (and all subobjects) loaded from the server are going to be plain object literals and not instances of the original type they were stored with.