User Guide
Everything you need to install, configure, and build with Montycat — from getting started to governance, advanced operations, and security.
Lookup
Lookup overview
Montycat provides efficient lookup mechanisms to retrieve records stored within keyspaces.
Lookups can be performed either by keys only (identifiers) or by values (full record contents).
These operations leverage Montycat's automatic indexing on structured data across in-memory and persistent storage engines.
All lookups can be refined using field-based criteria, timestamps, schemas, and pointer references.
Results are ordered by internal insertion timestamp. Pass order: "ascending" or order: "descending" to choose the direction explicitly.
Lookup keys
Retrieves only the unique keys of records that match the specified search criteria.
This is useful when you only need record references without fetching full payload values immediately.
Features:
- Filter by field values (e.g., username, age, location).
- Filter by timestamps (before/after/range conditions).
- Filter by schema type to ensure type-safe lookups.
- Follow pointers (foreign-key style references to other keyspaces).
Empty results return a structured empty array.
Example use case: Identify all employee records from the IT department hired after a specific date, but retrieve only their record keys (ids).
from keyspaces import Employees, Departments #keyspaces.py
from schemas import EmployeesSchema, DepartmentSchema #schemas.py
from montycat import Pointer, Timestamp
import datetime
department = DepartmentSchema(
name='IT',
employees=20
).serialize()
res1 = await Departments.insert_value(department)
# {"status": True, "payload": "128345335674100726154823618391811195396", "error": None}
record = EmployeesSchema(
username="Name",
location="Location",
age=21,
department=Pointer(Departments, '128345335674100726154823618391811195396'), # pass previously returned key,
dateHired=Timestamp(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
).serialize()
res2 = await Employees.insert_value(record)
# {"status": True, "payload": "128222336824100726154851618391811195396", "error": None}
res3 = await Employees.lookup_keys_where(
age = 21,
username = "Name",
)
# {"status": True, "payload": ["128222336824100726154851618391811195396"], "error": None}
res4 = await Employees.lookup_keys_where(
age = 21,
username = "Name",
dateHired: Timestamp(after='2025-06-10 12:00:00'),
department=Pointer(Departments, '128345335674100726154823618391811195396'),
schema=EmployeesSchema
)
# {"status": True, "payload": ["128222336824100726154851618391811195396"], "error": None}Lookup values
Retrieves the full record contents matching given criteria.
Unlike lookup_keys_where, this returns complete objects with field values.
Features:
- Supports the same filters as key lookups (field values, timestamps, schema, pointers).
- Optionally return resolved pointer data, so foreign-key references are automatically dereferenced into their corresponding values.
Example use case: Retrieve all details of employees named "Name", aged 21, hired after a given date, including department information via pointer resolution.
from keyspaces import Employees, Departments #keyspaces.py
from schemas import EmployeesSchema, DepartmentSchema #schemas.py
from montycat import Pointer, Timestamp
import datetime
department = DepartmentSchema(
name='IT',
employees=20
).serialize()
res1 = await Departments.insert_value(department)
# {"status": True, "payload": "128345335674100726154823618391811195396", "error": None}
record = EmployeesSchema(
username="Name",
location="Location",
age=21,
department=Pointer(Departments, '128345335674100726154823618391811195396'), # pass previously returned key,
dateHired=Timestamp(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
).serialize()
res2 = await Employees.insert_value(record)
# {"status": True, "payload": "128222336824100726154851618391811195396", "error": None}
res3 = await Employees.lookup_values_where(
age = 21,
username = "Name",
)
# {
# "status": True,
# "payload": [{"username": "Name", "location": "Location", "age": 21, "dateHired": "2025-08-10 12:00:00"}],
# "error": None
# }
res4 = await Employees.lookup_values_where(
age=21,
username="Name",
key_included=True # embed key with key_included argument
)
# {
# "status": True,
# "payload": [
# {
# "__key__": "128222336824100726154851618391811195396",
# "__value__": {"username": "Name", "location": "Location", "age": 21, "dateHired": "2025-08-10 12:00:00"}
# }
# ],
# "error": None
# }
res5 = await Employees.lookup_values_where(
age=21,
username="Name",
dateHired=Timestamp(after='2025-06-10 12:00:00'),
department=Pointer(Departments, '128345335674100726154823618391811195396'),
schema=EmployeesSchema
)
# {
# "status": True,
# "payload": [{"username": "Name", "location": "Location", "age": 21, "dateHired": "2025-08-10 12:00:00"}],
# "error": None
# }Lookup limit range
You can limit output using a range (start, stop) to handle pagination or large datasets.
This works for both in-memory and persistent keyspaces. The range is half-open ([start, stop)) and is applied after selecting the requested order, so reverse pagination is stable as well.
Ordering applies to key and value lookups. Semantic search is different: it remains similarity-ranked and does not accept key ordering.
from keyspaces import Employees #keyspaces.py
from montycat import ResultOrder
res1 = await Employees.lookup_keys_where(
age = 21,
username = "Name",
limit=[10, 1000],
order=ResultOrder.ASCENDING,
)
# {"status": True, "payload": ["128222336824100726154851618391811195396"], "error": None}
res2 = await Employees.lookup_values_where(
age = 21,
username = "Name",
limit=[10, 1000],
order=ResultOrder.ASCENDING,
)
# {
# "status": True,
# "payload": [{"username": "Name", "location": "Location", "age": 21, "dateHired": "2025-08-10 12:00:00"}],
# "error": None
# }Lookup retrieve with pointers
When working with relational data across keyspaces, Montycat supports pointers (foreign-key style references).
By enabling pointers flag, lookups will automatically resolve and return the full referenced objects.
from keyspaces import Employees #keyspaces.py
res1 = await Employees.lookup_values_where(
age = 21,
username = "Name",
with_pointers = True
)
# {
# "status": True,
# "payload": [
# {
# "username": "Name",
# "location": "Location",
# "age": 21,
# "department": {
# "name": "IT",
# "employees": 20
# },
# "dateHired": "2025-08-10 12:00:00"
# }
# ],
# "error": None
# }
# with pointers metadata enabled
res2 = await Employees.lookup_values_where(
age=21,
username="Name",
pointers_metadata=True
)
# {
# "status": True,
# "payload": [
# {
# "username": "Name",
# "location": "Location",
# "age": 21,
# "department": {
# "__keyspace__": "departments",
# "__key__": "128345335674100726154823618391811195396",
# },
# "dateHired": "2025-08-10 12:00:00"
# }
# ],
# "error": None
# }