Language
C# Java
Article For
1.0 2.0 2.5 4.0 4.1 4.2 5.0 5.1 5.3

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]);
Parameters
id string Identifier of a document that will be loaded.
documentType function A class constructor used for reviving the results' entities
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]);
session.load(idsArray, [options]);
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.
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]);

session.advanced.loadStartingWithIntoStream(idPrefix, output, [options]);
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
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
    });

ConditionalLoad

The conditionalLoad method takes a document's change vector. If the entity is tracked by the session, this method returns the entity. If the entity is not tracked, it checks if the provided change vector matches the document's current change vector on the server side. If they match, the entity is not loaded. If the change vectors do not match, the document is loaded.

In other words, this method can be used to check whether a document has been modified since the last time its change vector was recorded, so that the cost of loading it can be saved if it has not been modified.

The method is accessible from the session.advanced operations.

(object, changeVector) conditionalLoad<object>(id, changeVector);
Parameter Type Description
id string The identifier of a document to be loaded.
changeVector string The change vector you want to compare with the server-side change vector. If the change vectors match, the document is not loaded.
Return Type Description
ValueTuple (object, changeVector) If the given change vector and the server side change vector do not match, the method returns the requested entity and its current change vector.
If the change vectors match, the method returns default as the entity, and the current change vector.
If the specified document, the method returns only default without a change vector.

Example

var session = store.openSession();
session.store(user, "users/1");
session.saveChanges();

const changeVector = session.advanced.getChangeVectorFor(user);

// New session which does not track our User entity
// The given change vector matches 
// the server-side change vector
// Does not load the document
var session = store.openSession();
var result1 = session.advanced
    .conditionalLoad<User>("users/1", changeVector);

// Modify the document
user.name = "Bob Smith";
session.store(user);
session.saveChanges();

// Change vectors do not match
// Loads the document
var result2 = session.advanced
    .conditionalLoad<User>("users/1", changeVector);

Stream

Entities can be streamed from the server using the stream() method from the advanced session operations.

// stream query results
session.stream(query, [statsCallback]);

// stream documents with ID starting with
session.stream(idPrefix, [options]);
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.)
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.

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.