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.