Query Overview
-
Queries in RavenDB can be written with either of the following:
- Using a rich API via session's
query
method - Using the document_query method
-
Using RQL -
- when querying via session's
raw_query
method - when querying through Studio's Query view
- when querying via session's
- Using a rich API via session's
-
Queries defined with
query
ordocument_query
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 returns a projection
- Tracking is disabled
-
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.
-
Query type: Index query
Index used: Static-index -
You can specify which 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:
-
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 - query full collection | query by ID:
-
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 using session's
query
method. -
The following examples show dynamic queries that do not specify which index to use.
Please refer to querying an index for other examples. -
Querying can be enhanced using these extension methods.
Query collection - no filtering
# This is a Full Collection Query
# No auto-index is created since no filtering is applied
all_employees = list( # Execute the query
session.query(object_type=Employee) # Query for all documents from 'Employees' collection
)
# This is a Full Collection Query
# No auto-index is created since no filtering is applied
# Query for all documents from 'Employees' collection
query = session.query(object_type=Employee)
# Execute the query
all_employees = list(query)
# 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
employee = (
session.query(object_type=Employee)
.where_equals("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
# Query for specific document from 'Employees' collection
query = session.query(object_type=Employee).where_equals("Id", "employees/1-A")
# Execute the query
employee_result = query.first()
# 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
employees = list( # Execute the query
session.query(object_type=Employee).where_equals(
"first_name", "Robert"
) # Query for all 'Employee' documents that match this predicate
)
# 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
# Query for all 'Employee' documents that match this predicate
query = session.query(object_type=Employee).where_equals("first_name", "Robert")
# Execute the query
employees = list(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
products = list() # 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
query = (
session.query(object_type=Product).skip(5).take(10) # Skip first 5 results
) # Load up to 10 entities from 'Products' collection
# Execute the query
products = list(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.document_query
-
Below is a simple
document_query
usage sample and its RQL equivalent.
For a full description and more examples see:
Example:
# Query with document_query - filter by document field
# An auto-index will be created if there isn't already an existing auto-index
# that indexes this document field
employees = list( # Execute the query
session.advanced.document_query(object_type=Employee).where_equals( # Use document_query
"first_name", "Robert"
) # Query for all 'Employee' documents that match this predicate
)
# 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"
session.advanced.raw_query
-
Queries defined with query or document_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
raw_query
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
employees = list( # Execute the query
session.advanced.raw_query(
"from 'Employees' where first_name = 'Robert'", object_type=Employee
) # Provide RQL to RawQuery
)
# The resulting 'Employee' entities are loaded and will be tracked by the session
Custom methods
Available custom methods for session's query method:
- aggregate_by
- count
- count_lazily
- customize
- highlight
- include
- intersect
- lazily
- long_count
- more_like_this
- if_type
- order_by_distance
- order_by_distance_descending
- order_by_score
- order_by_score_descending
- project_into
- search
- spatial
- statistics
- suggest_using
Syntax
# Overloads for querying a collection OR an index:
# ================================================
def query(
self, source: Optional[Query] = None, object_type: Optional[Type[_T]] = None
) -> DocumentQuery[_T]:
...
def query_collection(
self, collection_name: str, object_type: Optional[Type[_T]] = None
) -> DocumentQuery[_T]:
...
def query_index(self, index_name: str, object_type: Optional[Type[_T]] = None) -> DocumentQuery[_T]:
...
def document_query(
self,
index_name: str = None,
collection_name: str = None,
object_type: Type[_T] = None,
is_map_reduce: bool = False,
) -> DocumentQuery[_T]:
...
# Overloads for querying an index:
# ================================
def query_index_type(
self, index_type: Type[_TIndex], object_type: Optional[Type[_T]] = None
) -> DocumentQuery[_T]:
...
def document_query_from_index_type(
self, index_type: Type[_TIndex], object_type: Type[_T]
) -> DocumentQuery[_T]:
...
# RawQuery
# ================================
def raw_query(self, query: str, object_type: Optional[Type[_T]] = None) -> RawDocumentQuery[_T]:
...
Parameter | Type | Description |
---|---|---|
object_type | Type[_T] |
Queried entities type |
collection_name | str |
Queried collection name |
query | str |
RQL query string |
index_name | str |
Queried index name |
index_type | Type[_TIndex] |
Queried index type |
is_map_reduce | bool |
Is a map-reduce index queried |
Return Value | |
---|---|
DocumentQuery[_T] RawDocumentQuery[_T] |
Instances exposing additional query methods and extensions |