Stream Query Results

RavenDB supports streaming data from the server to the client.
Streaming is useful when processing a large number of results.

The data streamed can be a result of a dynamic query, a static index query, or just filtered by a prefix.

To stream results, use the stream method from the advanced session operations.


Streaming overview

  • Immediate processing:
    Neither the client nor the server holds the full response in memory.
    Instead, as soon as the server has a single result, it sends it to the client.
    Thus, your application can start processing results before the server sends them all.

  • No tracking:
    The stream results are Not tracked by the session.
    Changes made to the resulting entities will not be sent to the server when saveChanges is called.

  • A snapshot of the data:
    The stream results are a snapshot of the data at the time when the query is computed by the server.
    Results that match the query after it was already processed are Not streamed to the client.

  • Query limitations::

    • A streaming query does not wait for indexing by design.
      So calling waitForNonStaleResults is Not supported and will result in an exception.

    • Using include to load a related document to the session in a streaming query is Not supported.

Syntax

<T> CloseableIterator<StreamResult<T>> stream(IDocumentQuery<T> query);

<T> CloseableIterator<StreamResult<T>> stream(IDocumentQuery<T> query, Reference<StreamQueryStatistics> streamQueryStats);

<T> CloseableIterator<StreamResult<T>> stream(IRawDocumentQuery<T> query);

<T> CloseableIterator<StreamResult<T>> stream(IRawDocumentQuery<T> query, Reference<StreamQueryStatistics> streamQueryStats);
Parameters
query IDocumentQuery or IRawDocumentQuery Query to stream results for.
Reference streamQueryStats StreamQueryStatistics Information about performed query.
Return Value
CloseableIterator Iterator with entities.

Example I - Using Static Index

IDocumentQuery<Employee> query = session
    .query(Employee.class, Employees_ByFirstName.class)
    .whereEquals("FirstName", "Robert");

CloseableIterator<StreamResult<Employee>> results = session.advanced().stream(query);

while (results.hasNext()) {
    StreamResult<Employee> employee = results.next();
}

Example II - Dynamic Document Query

IDocumentQuery<Employee> query = session
    .advanced()
    .documentQuery(Employee.class)
    .whereEquals("FirstName", "Robert");

Reference<StreamQueryStatistics> streamQueryStatsRef = new Reference<>();
CloseableIterator<StreamResult<Employee>> results = session.advanced().stream(query, streamQueryStatsRef);

while (results.hasNext()) {
    StreamResult<Employee> employee = results.next();
}

Example III - Dynamic Raw Query

IRawDocumentQuery<Employee> query = session.advanced()
    .rawQuery(Employee.class, "from Employees where FirstName = 'Robert'");

CloseableIterator<StreamResult<Employee>> results = session.advanced().stream(query);

while (results.hasNext()) {
    StreamResult<Employee> employee = results.next();
}