Querying an Index
-
Prior to this article, it is recommended that you first read this Query Overview.
-
For a basic indexes overview, see the Indexes Overview.
-
Indexing the content of your documents allows for fast document retrieval when querying the index.
-
This article is a basic overview of how to query a static index using code.
- For dynamic query examples see Query Overview.
- An index can also be queried from Studio using RQL.
-
In this page:
Query an index by query_index_type
and query_index
-
In the following examples we query an index using the session
query_index_type
andquery_index
methods. -
Querying can be enhanced using these extension methods.
Query index - no filtering:
# Query the 'Employees' collection using the index - without filtering
# (Open the 'Index' tab to view the index class definition)
employees = list(
session
# Pass the queried collection as the first generic parameter
# Pass the index class as the second generic parameter
.query_index_type(Employees_ByName, Employee)
)
# All 'Employee' documents that contain DOCUMENT-fields 'FirstName' and\or 'LastName' will be returned
# Query the 'Employees' collection using the index - without filtering
employees = list(
session
# Pass the index name as a parameter
# Use slash '/' in the index name, replacing the underscore '_' from the index class definition
.query_index("Employees/ByName")
)
# All 'Employee' documents that contain DOCUMENT-fields 'FirstName' and\or 'LastName' will be returned
# The index definition:
class Employees_ByName(AbstractIndexCreationTask):
# The IndexEntry class defines the index-fields
class IndexEntry:
def __init__(self, first_name: str = None, last_name: str = None):
self.first_name = first_name
self.last_name = last_name
# The from_json method to handle different casing on the server
@classmethod
def from_json(cls, json_dict: Dict[str, Any]) -> "Employees_ByName.IndexEntry":
return cls(json_dict["FirstName"], json_dict["LastName"])
def __init__(self):
super().__init__()
# The 'map' function defines the content of the INDEX-fields
# * The content of INDEX-fields 'FirstName' & 'LastName'
# is composed of the relevant DOCUMENT-fields.
self.map = """from e in docs.Employees select new {FirstName = e.FirstName, LastName = e.LastName}"""
# * The index-fields can be queried on to fetch matching documents.
# You can query and filter Employee documents based on their first or last names.
# * Employee documents that do Not contain both 'FirstName' and 'LastName' fields
# will Not be indexed.
# * Note: the INDEX-field name does Not have to be exactly the same
# as the DOCUMENT-field name.
// Note:
// Use slash `/` in the index name, replacing the underscore `_` from the index class definition
from index "Employees/ByName"
// All 'Employee' documents that contain DOCUMENT-fields 'FirstName' and\or 'LastName' will be returned
Query index - with filtering:
# Query the 'Employees' collection using the index - filter by INDEX-field
employees = list(
session
# Pass the index class as the first parameter
# Pass the IndexEntry class as the second parameter
.query_index_type(Employees_ByName, Employees_ByName.IndexEntry)
# Filter the retrieved documents by some predicate on an INDEX-field
.where_equals("LastName", "King")
# Specify the type of the returned document entities
.of_type(Employee)
)
# Results will include all documents from 'Employees' collection whose 'LastName' equals to 'King'
# The index definition:
class Employees_ByName(AbstractIndexCreationTask):
# The IndexEntry class defines the index-fields
class IndexEntry:
def __init__(self, first_name: str = None, last_name: str = None):
self.first_name = first_name
self.last_name = last_name
# The from_json method to handle different casing on the server
@classmethod
def from_json(cls, json_dict: Dict[str, Any]) -> "Employees_ByName.IndexEntry":
return cls(json_dict["FirstName"], json_dict["LastName"])
def __init__(self):
super().__init__()
# The 'map' function defines the content of the INDEX-fields
# * The content of INDEX-fields 'FirstName' & 'LastName'
# is composed of the relevant DOCUMENT-fields.
self.map = """from e in docs.Employees select new {FirstName = e.FirstName, LastName = e.LastName}"""
# * The index-fields can be queried on to fetch matching documents.
# You can query and filter Employee documents based on their first or last names.
# * Employee documents that do Not contain both 'FirstName' and 'LastName' fields
# will Not be indexed.
# * Note: the INDEX-field name does Not have to be exactly the same
# as the DOCUMENT-field name.
// Note:
// Use slash `/` in the index name, replacing the underscore `_` from the index class definition
from index "Employees/ByName"
where LastName == "King"
// Results will include all documents from 'Employees' collection whose 'LastName' equals to 'King'.
-
of_type
is used to convert the type being used in the where clause (IndexEntry
)
to the collection type (Employee
).
The reason for this is that while theIndexEntry
type allows for a strongly typed query,
the server returns the actual documents entities objects. -
An exception will be thrown when filtering by fields that are Not defined in the index.
-
Read more about filtering here.
Query index - with paging:
# Query the 'Employees' collection using the index - page results
# This example is based on the previous filtering example
employees = list(
session.query_index_type(Employees_ByName, Employees_ByName.IndexEntry)
.where_equals("LastName", "King")
.skip(5) # Skip first 5 results
.take(10) # Retrieve up to 10 documents
.of_type(Employee)
)
# Results will include up to 10 matching documents
# The index definition:
class Employees_ByName(AbstractIndexCreationTask):
# The IndexEntry class defines the index-fields
class IndexEntry:
def __init__(self, first_name: str = None, last_name: str = None):
self.first_name = first_name
self.last_name = last_name
# The from_json method to handle different casing on the server
@classmethod
def from_json(cls, json_dict: Dict[str, Any]) -> "Employees_ByName.IndexEntry":
return cls(json_dict["FirstName"], json_dict["LastName"])
def __init__(self):
super().__init__()
# The 'map' function defines the content of the INDEX-fields
# * The content of INDEX-fields 'FirstName' & 'LastName'
# is composed of the relevant DOCUMENT-fields.
self.map = """from e in docs.Employees select new {FirstName = e.FirstName, LastName = e.LastName}"""
# * The index-fields can be queried on to fetch matching documents.
# You can query and filter Employee documents based on their first or last names.
# * Employee documents that do Not contain both 'FirstName' and 'LastName' fields
# will Not be indexed.
# * Note: the INDEX-field name does Not have to be exactly the same
# as the DOCUMENT-field name.
// Note:
// Use slash `/` in the index name, replacing the underscore `_` from the index class definition
from index "Employees/ByName"
where LastName == "King"
limit 5, 10 // skip 5, take 10
- Read more about paging here.
Query an index by raw_query
-
Queries defined with Query or DocumentQuery 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
session.advanced.raw_query
method.
Example:
# Query with RawQuery - filter by INDEX-field
employees = list(
session.advanced
# Provide RQL to raw_query
.raw_query("from index 'Employees/ByName' where LastName == 'King'", Employee)
)
# Results will include all documents from 'Employees' collection whose 'LastName' equals to 'King'.
# The index definition:
class Employees_ByName(AbstractIndexCreationTask):
# The IndexEntry class defines the index-fields
class IndexEntry:
def __init__(self, first_name: str = None, last_name: str = None):
self.first_name = first_name
self.last_name = last_name
# The from_json method to handle different casing on the server
@classmethod
def from_json(cls, json_dict: Dict[str, Any]) -> "Employees_ByName.IndexEntry":
return cls(json_dict["FirstName"], json_dict["LastName"])
def __init__(self):
super().__init__()
# The 'map' function defines the content of the INDEX-fields
# * The content of INDEX-fields 'FirstName' & 'LastName'
# is composed of the relevant DOCUMENT-fields.
self.map = """from e in docs.Employees select new {FirstName = e.FirstName, LastName = e.LastName}"""
# * The index-fields can be queried on to fetch matching documents.
# You can query and filter Employee documents based on their first or last names.
# * Employee documents that do Not contain both 'FirstName' and 'LastName' fields
# will Not be indexed.
# * Note: the INDEX-field name does Not have to be exactly the same
# as the DOCUMENT-field name.
// Note:
// Use slash `/` in the index name, replacing the underscore `_` from the index class definition
from index "Employees/ByName"
where LastName == "King"