Querying an Index




Query an index by query_index_type and query_index

  • In the following examples we query an index using the session query_index_type and query_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 the IndexEntry 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"