Materialized Views API Reference

This module provides support for creating and managing materialized views in SurrealDB for improved query performance on aggregated data.

Core Classes

class surrealengine.materialized_view.MaterializedView(name, query, refresh_interval=None, document_class=None, aggregations=None, select_fields=None)[source]

Bases: object

Materialized view for SurrealDB.

This class represents a materialized view in SurrealDB, which is a precomputed view of data that can be used to improve query performance for frequently accessed aggregated data.

name

The name of the materialized view

query

The query that defines the materialized view

refresh_interval

The interval at which the view is refreshed

document_class

The document class that the view is based on

aggregations

Dictionary of field names and aggregation functions

select_fields

List of fields to select (if None, selects all fields)

__init__(name, query, refresh_interval=None, document_class=None, aggregations=None, select_fields=None)[source]

Initialize a new MaterializedView.

Parameters:
  • name (str) – The name of the materialized view

  • query (QuerySet) – The query that defines the materialized view

  • refresh_interval (str) – The interval at which the view is refreshed (e.g., “1h”, “30m”)

  • document_class (Type['Document']) – The document class that the view is based on

  • aggregations (Dict[str, Aggregation]) – Dictionary of field names and aggregation functions

  • select_fields (List[str]) – List of fields to select (if None, selects all fields)

async create(connection=None, overwrite=False, if_not_exists=False)[source]

Create the materialized view in the database.

Parameters:
  • connection – The database connection to use (optional)

  • overwrite (bool) – Whether to overwrite the table if it exists (default: False)

  • if_not_exists (bool) – Whether to create the table only if it does not exist (default: False)

create_sync(connection=None, overwrite=False, if_not_exists=False)[source]

Create the materialized view in the database synchronously.

Parameters:
  • connection – The database connection to use (optional)

  • overwrite (bool) – Whether to overwrite the table if it exists (default: False)

  • if_not_exists (bool) – Whether to create the table only if it does not exist (default: False)

async drop(connection=None)[source]

Drop the materialized view from the database.

Parameters:

connection – The database connection to use (optional)

drop_sync(connection=None)[source]

Drop the materialized view from the database synchronously.

Parameters:

connection – The database connection to use (optional)

async refresh(connection=None)[source]

Manually refresh the materialized view.

DEPRECATED: SurrealDB views derived from TABLES are live and do not need manual refresh. This method will be removed in a future version.

Parameters:

connection – The database connection to use (optional)

refresh_sync(connection=None)[source]

Manually refresh the materialized view.

DEPRECATED: SurrealDB views derived from TABLES are live and do not need manual refresh. This method will be removed in a future version.

Parameters:

connection – The database connection to use (optional)

property objects: QuerySet

Get a QuerySet for querying the materialized view.

Returns:

A QuerySet for querying the materialized view

async execute_raw_query(connection=None)[source]

Execute a raw query against the materialized view.

This is a workaround for the “no decoder for tag” error that can occur when querying materialized views using the objects property.

Parameters:

connection – The database connection to use (optional)

Returns:

The query results

execute_raw_query_sync(connection=None)[source]

Execute a raw query against the materialized view synchronously.

This is a workaround for the “no decoder for tag” error that can occur when querying materialized views using the objects property.

Parameters:

connection – The database connection to use (optional)

Returns:

The query results

Aggregation Functions

Base Aggregation

class surrealengine.materialized_view.Aggregation(field=None)[source]

Bases: object

Base class for aggregation functions.

This class represents an aggregation function that can be used in a materialized view. Subclasses should implement the __str__ method to return the SurrealQL representation of the aggregation function.

__init__(field=None)[source]

Initialize a new Aggregation.

Parameters:

field (str) – The field to aggregate (optional)

__str__()[source]

Return the SurrealQL representation of the aggregation function.

Statistical Aggregations

class surrealengine.materialized_view.Count(field=None)[source]

Bases: Aggregation

Count aggregation function.

This class represents the count() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the count function.

class surrealengine.materialized_view.Mean(field=None)[source]

Bases: Aggregation

Mean aggregation function.

This class represents the math::mean() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the mean function.

class surrealengine.materialized_view.Sum(field=None)[source]

Bases: Aggregation

Sum aggregation function.

This class represents the math::sum() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the sum function.

class surrealengine.materialized_view.Min(field=None)[source]

Bases: Aggregation

Min aggregation function.

This class represents the math::min() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the min function.

class surrealengine.materialized_view.Max(field=None)[source]

Bases: Aggregation

Max aggregation function.

This class represents the math::max() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the max function.

class surrealengine.materialized_view.Median(field=None)[source]

Bases: Aggregation

Median aggregation function.

This class represents the math::median() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the median function.

class surrealengine.materialized_view.StdDev(field=None)[source]

Bases: Aggregation

Standard deviation aggregation function.

This class represents the math::stddev() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the standard deviation function.

class surrealengine.materialized_view.Variance(field=None)[source]

Bases: Aggregation

Variance aggregation function.

This class represents the math::variance() aggregation function in SurrealQL.

__str__()[source]

Return the SurrealQL representation of the variance function.

class surrealengine.materialized_view.Percentile(field=None, percentile=50)[source]

Bases: Aggregation

Percentile aggregation function.

This class represents the math::percentile() aggregation function in SurrealQL.

__init__(field=None, percentile=50)[source]

Initialize a new Percentile.

Parameters:
  • field (str) – The field to aggregate (optional)

  • percentile (float) – The percentile to calculate (default: 50)

__str__()[source]

Return the SurrealQL representation of the percentile function.

Collection Aggregations

class surrealengine.materialized_view.ArrayCollect(field=None)[source]

Bases: ArrayGroup

class surrealengine.materialized_view.Distinct(field=None)[source]

Bases: Aggregation

Distinct aggregation function.

This class represents a distinct-of-values across grouped rows. Safe for scalar fields by wrapping each row’s value in an array first.

__str__()[source]

Return the SurrealQL representation of the distinct function.

class surrealengine.materialized_view.GroupConcat(field=None, separator=', ')[source]

Bases: Aggregation

Group concatenation aggregation function.

This class represents a custom aggregation function that concatenates values with a separator.

__init__(field=None, separator=', ')[source]

Initialize a new GroupConcat.

Parameters:
  • field (str) – The field to aggregate (optional)

  • separator (str) – The separator to use (default: “, “)

__str__()[source]

Return the SurrealQL representation of the group concat function.

Usage Examples

Basic Materialized View

from surrealengine import Document, StringField, IntField, DateTimeField
from surrealengine.materialized_view import MaterializedView, Count, Mean

class Order(Document):
    customer_id = StringField(required=True)
    amount = DecimalField(required=True)
    status = StringField(required=True)
    created_at = DateTimeField(auto_now_add=True)

# Create a materialized view for order statistics
order_stats = MaterializedView(
    name="order_statistics",
    query=Order.objects.group_by("customer_id"),
    aggregations={
        "total_orders": Count(),
        "avg_order_amount": Mean("amount"),
        "total_spent": Sum("amount")
    },
    refresh_interval="1h"
)

# Create the view in the database
await order_stats.create()

Document-Based Materialized Views

# Create materialized view using Document class method
customer_summary = Order.create_materialized_view(
    name="customer_summary",
    query=Order.objects.filter(status="completed").group_by("customer_id"),
    aggregations={
        "completed_orders": Count(),
        "total_revenue": Sum("amount"),
        "avg_order_value": Mean("amount"),
        "last_order_date": Max("created_at")
    },
    refresh_interval="30m"
)

await customer_summary.create()

Advanced Aggregations

from surrealengine.materialized_view import (
    Percentile, StdDev, ArrayCollect, GroupConcat
)

# Advanced statistics view
advanced_stats = MaterializedView(
    name="advanced_order_stats",
    query=Order.objects.group_by("status"),
    aggregations={
        "order_count": Count(),
        "amount_p95": Percentile("amount", 95),
        "amount_std": StdDev("amount"),
        "customer_list": ArrayCollect("customer_id"),
        "customer_names": GroupConcat("customer_name", separator=", ")
    }
)

Time-Based Materialized Views

# Daily sales summary
daily_sales = MaterializedView(
    name="daily_sales",
    query=Order.objects.group_by("DATE(created_at)"),
    aggregations={
        "daily_revenue": Sum("amount"),
        "daily_orders": Count(),
        "unique_customers": Distinct("customer_id")
    },
    refresh_interval="1h"
)

Querying Materialized Views

# Query the materialized view
stats = await order_stats.query()
for row in stats:
    print(f"Customer {row['customer_id']}: {row['total_orders']} orders")

# Query with filters
high_value_customers = await order_stats.query(
    filter_condition="total_spent > 1000"
)

# Get view metadata
info = await order_stats.info()
print(f"View last refreshed: {info['last_refresh']}")

Managing Materialized Views

# Refresh view manually
await order_stats.refresh()

# Update view definition
await order_stats.update(
    aggregations={
        "total_orders": Count(),
        "avg_order_amount": Mean("amount"),
        "max_order_amount": Max("amount")  # Added new aggregation
    }
)

# Drop view
await order_stats.drop()

# Check if view exists
exists = await order_stats.exists()

Integration with Query Pipeline

from surrealengine.aggregation import AggregationPipeline

# Create aggregation pipeline that can be used for materialized views
pipeline = AggregationPipeline(Order) \\
    .match(status="completed") \\
    .group_by("customer_id") \\
    .aggregate(
        total_spent=Sum("amount"),
        order_count=Count(),
        avg_amount=Mean("amount")
    )

# Create materialized view from pipeline
customer_stats = MaterializedView.from_pipeline(
    name="customer_stats_mv",
    pipeline=pipeline,
    refresh_interval="2h"
)

await customer_stats.create()

Performance Monitoring

# Monitor view performance
async def monitor_view_performance():
    views = [order_stats, customer_summary, daily_sales]

    for view in views:
        info = await view.info()
        print(f"View: {view.name}")
        print(f"  Size: {info.get('size', 'Unknown')}")
        print(f"  Last refresh: {info.get('last_refresh', 'Unknown')}")
        print(f"  Refresh duration: {info.get('refresh_duration', 'Unknown')}")
        print()

await monitor_view_performance()