# Implement Reusable Metric Store > This document describes how to use AML Extend to reuse metrics ## Overview With [AML Extend](/reference/aml/extend), you can define metrics once and reuse them across multiple datasets. This approach helps you: - Avoid duplicating logic for every new business question - Manage important business logic in one central place - Maintain a lean analytics codebase that's easier for new team members to learn ## Key Concepts Before diving into examples, understand these two approaches for organizing reusable metrics: 1. **Define metrics separately** - Metrics can be declared as standalone objects, making them independently reusable 2. **Group metrics with PartialDataset** - Related metrics can be organized into thematic groups using `PartialDataset` for easier management and reuse You can mix both approaches to build a flexible metric store that suits your team's needs. ## How to Reuse Metrics ### Approach 1: Define Metrics Separately You can define individual metrics as standalone objects and reference them when needed: ```aml title="metrics.aml" // Define standalone metrics Metric total_orders { label: "Total Orders" type: "number" description: "Total number of orders placed" definition: @aql count(ecommerce_orders.id);; } Metric gmv { label: "GMV (Gross Merchandise Value)" type: "number" description: "Total value of all orders before discount" definition: @aql ecommerce_order_items | sum(ecommerce_order_items.quantity * ecommerce_products.price);; format: "[\$\$]#,###0" } Metric revenue { label: "Total Revenue" type: "number" description: "Total revenue after applying commission rate" definition: @aql nmv * revenue_commission;; format: "[\$\$]#,###0" } Metric aov { label: "AOV (Average Order Value)" type: "number" description: "Average value per order" definition: @aql gmv / total_orders;; format: "[\$\$]#,###0" } ``` Then extend your dataset with individual metrics: ```aml title = "company.dataset.aml" Dataset company { // Base dataset definition // Omitted for brevity } // Add individual metrics to the dataset // highlight-next-line Dataset company_with_metrics = company.extend({ metric total_orders: total_orders metric gmv: gmv metric revenue: revenue }) ``` ### Approach 2: Group Related Metrics with PartialDataset For better organization, group related metrics into thematic `PartialDataset` objects. This makes it easier to reuse entire groups of metrics: ```aml title="metrics.aml" // Define individual metrics first Metric total_orders { label: "Total Orders" type: "number" definition: @aql count(ecommerce_orders.id);; } Metric total_delivered_orders { label: "Total Delivered Orders" type: "number" definition: @aql total_orders | where(ecommerce_orders.status is 'delivered');; } Metric total_cancelled_orders { label: "Total Cancelled Orders" type: "number" definition: @aql total_orders | where(ecommerce_orders.status is 'cancelled');; } Metric gmv { label: "GMV (Gross Merchandise Value)" type: "number" definition: @aql ecommerce_order_items | sum(ecommerce_order_items.quantity * ecommerce_products.price);; format: "[\$\$]#,###0" } Metric revenue { label: "Total Revenue" type: "number" definition: @aql nmv * revenue_commission;; format: "[\$\$]#,###0" } Metric aov { label: "AOV (Average Order Value)" type: "number" definition: @aql gmv / total_orders;; format: "[\$\$]#,###0" } // Group volume-related metrics // highlight-next-line PartialDataset volume_metrics { metric total_orders: total_orders metric total_delivered_orders: total_delivered_orders metric total_cancelled_orders: total_cancelled_orders } // Group revenue-related metrics // highlight-next-line PartialDataset revenue_metrics { metric gmv: gmv metric revenue: revenue metric aov: aov } ``` Now you can reuse these metric groups across different datasets: ```aml title="company.dataset.aml" Dataset company { // Omitted for brevity } // Extend with grouped metrics // highlight-next-line Dataset company_analytics = company .extend(volume_metrics) .extend(revenue_metrics) ``` ### Approach 3: Mix and Match - Chain Extensions You can combine both approaches, extending datasets with metric groups and individual metrics: ```aml title="store.dataset.aml" Dataset store { // Omitted for brevity } // Extend with metric groups and add custom metrics // highlight-next-line Dataset store_analytics = store .extend(volume_metrics) .extend(revenue_metrics) .extend({ // Add or override individual metrics metric store_specific_metric { label: "Store-Specific Metric" type: "number" definition: @aql gmv * (1 - store.discount_rate) } }) ``` ## Advanced: Parameterized Metrics with Functions When you need to reuse the same metric logic across different contexts (e.g., different regions, product lines, or data models), you can use [AML Functions](/reference/aml/func) to create parameterized metrics. ### The Problem: Duplicated Metric Logic Imagine you price products differently for US and UK markets using separate data models. Without parameterization, you'd duplicate the metric definition: ```aml // Without parameterization - duplicated logic PartialDataset regional_revenue_metrics { metric order_value_us { label: "Order Value (US)" type: "number" // highlight-next-line definition: @aql orders | sum(order_item.quantity * products_us.price) } metric order_value_uk { label: "Order Value (UK)" type: "number" // highlight-next-line definition: @aql orders | sum(order_item.quantity * products_uk.price) } } ``` Notice the formula is identical except for the product model reference. This duplication becomes harder to maintain as you add more regions. ### The Solution: Use Functions to Parameterize Metrics Instead, create a function that returns a `PartialDataset` with parameterized metrics: ```aml // Declare a function that accepts a product model as parameter // highlight-next-line Func getRevenueMetrics(product_model: Model) { PartialDataset revenue_metrics { metric order_value { label: "Order Value" type: "number" hidden: false // Use the product_model parameter in the definition // highlight-next-line definition: @aql orders | sum(order_item.quantity * ${product_model.name}.price) } metric gmv { label: "Gross Merchandise Value" type: "number" // highlight-next-line definition: @aql orders | sum(order_item.quantity * ${product_model.name}.price * (1 - orders.discount)) format: "[\$\$]#,###0" } } } ``` ### Reuse Parameterized Metrics Across Datasets Now you can reuse this metric logic for different regions by passing the appropriate product model: ```aml title="us_data.dataset.aml" Dataset us_market { // Base dataset definition // Omitted for brevity } // Extend with US product model // highlight-next-line Dataset us_market_with_revenue = us_market.extend(getRevenueMetrics(products_us)) // In uk_data.dataset.aml Dataset uk_market { // Base dataset definition // Omitted for brevity } // Extend with UK product model // highlight-next-line Dataset uk_market_with_revenue = uk_market.extend(getRevenueMetrics(products_uk)) ``` This approach ensures your metric logic stays consistent across regions while remaining flexible enough to adapt to different data models. ## Benefits of a Reusable Metric Store By implementing a metric store using the patterns above, you gain: 1. **Single Source of Truth** - Business logic defined once, used everywhere 2. **Easier Maintenance** - Update a metric definition in one place, all datasets benefit 3. **Consistency** - Same calculations across all reports and dashboards 4. **Scalability** - Add new metrics or metric groups without rewriting existing datasets 5. **Flexibility** - Mix and match metric groups, add custom metrics, or use parameterization for complex scenarios