Query Overview


  • Queries in RavenDB can be written with:

    • The session's query method - rich API is provided
    • The session's rawQuery method - using RQL
    • The Query view in Studio - using RQL
  • Queries defined with the query method are translated by the RavenDB client to RQL
    when sent to the server.


  • All queries in RavenDB use an index to provide results, even when you don't specify one.
    Learn more below.

  • Queries that do Not specify which index to use are called Dynamic Queries.
    This article displays examples of dynamic queries only.
    For examples showing how to query an index see querying an index.


  • The entities returned by the query are 'loaded' and tracked by the Session.
    Entities will Not be tracked when:

  • Query results are cached by default. To disable query caching see noCaching.

  • Queries are timed out after a configurable time period. See query timeout.



Queries always provide results using an index

  • Queries always use an index to provide fast results regardless of the size of your data.

  • When a query reaches a RavenDB instance, the instance calls its query optimizer to analyze the query
    and determine which index should be used to retrieve the requested data.

  • Indexes allow to provide query results without scanning the entire dataset each and every time.
    Learn more about indexes in indexes overview.

We differentiate between the following 3 query scenarios:

  • Index query
  • Dynamic query
  • Full collection query

For each scenario, a different index type will be used.

1. Query an existing index:

  • Query type: Index query
    Index used: Static-index

  • You can specify which STATIC-static index the query will use.

  • Static indexes are defined by the user, as opposed to auto-indexes that are created by the server
    when querying a collection with some filtering applied. See Static-index vs Auto-index.

  • Example RQL:   from index "Employees/ByFirstName" where FirstName == "Laura"
    See more examples in querying an index.

2. Query a collection - with filtering (Dynamic Query):

  • Query type: Dynamic Query
    Index used: Auto-index

  • When querying a collection without specifying an index and with some filtering condition
    (other than just the document ID) the query-optimizer will analyze the query to see if an AUTO-index
    that can answer the query already exists, i.e. an auto-index on the collection queried with index-fields that match those queried.

  • If such auto-index (Not a static one...) is found, it will be used to fetch the results.

  • Else, if no relevant auto-index is found,
    the query-optimizer will create a new auto-index with fields that match the query criteria.
    At this time, and only at this time, the query will wait for the auto-indexing process to complete.
    Subsequent queries that target this auto-index will be served immediately.

  • Note: if there exists an auto-index that is defined on the collection queried
    but is indexing a different field than the one queried on,
    then the query-optimizer will create a new auto-index that merges both the
    fields from the existing auto-index and the new fields queried.

  • Once the newly created auto-index is done indexing the data,
    the old auto-index is removed in favor of the new one.

  • Over time, an optimal set of indexes is generated by the query optimizer to answer your queries.

  • Example RQL:   from Employees where FirstName == "Laura"
    See more examples below.


  • Note: Counters and Time series are an exception to this flow.
    Dynamic queries on counters and time series values don't create auto-indexes.
    However, a static-index can be defined on Time series and Counters.

3. Query a collection - no filtering:

  • Query type: Full collection Query
    Index used: The raw collection (internal storage indexes)

  • Full collection query:

    • When querying a collection without specifying an index and with no filtering condition,
      then all documents from the specified collection are returned.

    • RavenDB uses the raw collection documents in its internal storage indexes as the source for this query.
      No auto-index is created.

    • Example RQL:   from Employees

  • Query by document ID:

    • When querying a collection only by document ID or IDs,
      then similar to the full collection query, no auto-index is created.

    • RavenDB uses the raw collection documents as the source for this query.

    • Example RQL:   from Employees where id() == "employees/1-A"
      See more examples below.

session.query

  • The simplest way to issue a query is by using the session's query method.
    Customize your query with these API methods.

  • The following examples show dynamic queries that do not specify which index to use.
    Please refer to querying an index for other examples.

Query collection - no filtering

// This is a Full Collection Query
// No auto-index is created since no filtering is applied

// Query for all documents from 'employees' collection
const employees = await session.query({ collection: "employees" })
    // Execute the query
    .all();

// All 'employee' entities are loaded and will be tracked by the session
// This is a Full Collection Query
// No auto-index is created since no filtering is applied

// Query for all documents from 'employees' collection
const employees = await session.query(Employee)
    // Execute the query
    .all();

// All 'employee' entities are loaded and will be tracked by the session
// This RQL is a Full Collection Query
// No auto-index is created since no filtering is applied

from "employees"

Query collection - by ID

// Query collection by document ID
// No auto-index is created when querying only by ID

const employee = await session.query({ collection: "employees" })
    .whereEquals("id()", "employees/1-A") // Query for specific document from 'employees' collection 
    .first();                             // Execute the query

// The resulting 'employee' entity is loaded and will be tracked by the session 
// Query collection by document ID
// No auto-index is created when querying only by ID

const employee = await session.query(Employee)
    .whereEquals("id()", "employees/1-A") // Query for specific document from 'employees' collection 
    .first();                             // Execute the query

// The resulting 'employee' entity is loaded and will be tracked by the session 
// This RQL queries the 'Employees' collection by ID
// No auto-index is created when querying only by ID

from "employees" where id() == "employees/1-A"

Query collection - with filtering

// Query collection - filter by document field

// An auto-index will be created if there isn't already an existing auto-index
// that indexes this document field

const employees = await session.query({ collection: "employees" })
    .whereEquals("firstName", "Robert") // Query for all 'employee' documents that match this predicate 
    .all();                             // Execute the query

// The resulting 'employee' entities are loaded and will be tracked by the session 
// Query collection - filter by document field

// An auto-index will be created if there isn't already an existing auto-index
// that indexes this document field

const employees = await session.query(Employee)
    .whereEquals("firstName", "Robert") // Query for all 'employee' documents that match this predicate 
    .all();                             // Execute the query

// The resulting 'employee' entities are loaded and will be tracked by the session 
// Query collection - filter by document field

// An auto-index will be created if there isn't already an existing auto-index
// that indexes the requested field

from "employees" where firstName == "Robert"

Query collection - with paging

// Query collection - page results
// No auto-index is created since no filtering is applied

const products = await session.query({ collection: "products" })
    .skip(5)  // Skip first 5 results
    .take(10) // Load up to 10 entities from 'products' collection
    .all();   // Execute the query

// The resulting 'product' entities are loaded and will be tracked by the session 
// Query collection - page results
// No auto-index is created since no filtering is applied

const products = await session.query(Employee)
    .skip(5)  // Skip first 5 results
    .take(10) // Load up to 10 entities from 'products' collection
    .all();   // Execute the query

// The resulting 'product' entities are loaded and will be tracked by the session 
// Query collection - page results
// No auto-index is created since no filtering is applied

from "products" limit 5, 10 // skip 5, take 10
  • By default, if the page size is not specified, all matching records will be retrieved from the database.

session.advanced.rawQuery

  • Queries defined with query are translated by the RavenDB client to RQL when sent to the server.

  • The session also gives you a way to express the query directly in RQL using the rawQuery method.

Example:

// Query with rawQuery - filter by document field

// An auto-index will be created if there isn't already an existing auto-index
// that indexes this document field

const employees = await session.advanced
     // Provide RQL to rawQuery
    .rawQuery("from employees where firstName = 'Robert'")
     // Execute the query
    .all();

// The resulting 'employee' entities are loaded and will be tracked by the session 

query API

Available methods for the session's query method:

Syntax

// Overload for querying a collection:
session.query(documentType);

// Overload for querying an index:
session.query(documentType, index);

// Overload for querying a collection OR an index:
session.query(opts);

// rawQuery:
session.rawQuery(query);
Parameter Type Description
documentType object The type of entities queried
index object The index class
opts DocumentQueryOptions object Query options
query string The RQL query string
DocumentQueryOptions
collection string
  • Collection name queried
indexName string
  • Index name queried
index object
  • Index object queried
  • Note:
    indexName & index are mutually exclusive with collection.
    See examples in querying an index.
Return Value
object Instance implementing IDocumentQuery exposing the additional query methods.
  • Note:
    Use await when executing the query, e.g. when calling .all, .single, .first, .count, etc.