Skip to main content
Metadata tags in Malloy serve two purposes: they document your model for human readers, and they enable AI agents to discover and understand your data through the Intelligent Context Engine. When you publish a model to Credible, metadata is indexed and becomes searchable—both by people browsing your models and by AI agents answering natural language questions.

Documentation Tags

Use #(doc) tags to add human-readable descriptions to fields. Place the tag on the line before the field definition.
source: orders is table('sales.orders') {
  dimension:
    #(doc) The unique identifier for each order
    order_id is id

    #(doc) The date when the order was placed
    order_date is created_at::date

    #(doc) Customer segment based on lifetime value: High (>$10k), Medium (>$1k), Low
    customer_segment is case
      when lifetime_value > 10000 then 'High'
      when lifetime_value > 1000 then 'Medium'
      else 'Low'
    end

  measure:
    #(doc) Total revenue from all orders
    total_revenue is sum(amount)

    #(doc) Average order value across all orders
    avg_order_value is avg(amount)

    #(doc) Number of orders that have shipped
    shipped_orders is count() { where: status = 'shipped' }
}

Value Indexing

Use #(index_values) to index distinct values from a column. This enables AI agents to find fields by searching for data values, not just field names or descriptions.
source: products is table('catalog.products') {
  dimension:
    #(index_values) n=-1
    #(doc) The product name
    product_name is name

    #(index_values) n=100
    #(doc) The product category (e.g., Electronics, Clothing, Home & Garden)
    category is product_category

    #(index_values) n=50
    #(doc) The brand name
    brand is brand_name
}
The n parameter specifies how many distinct values to index. Use n=-1 to index all values, or specify a number for high-cardinality fields where you only need a sample.

Why Value Indexing Matters

Consider a product catalog where the column is named product_category but contains values like “Running Shoes” and “Athletic Apparel”. Without value indexing, when a user asks an MCP-connected AI assistant “What are our top-selling sports gear products?”, the system can only search field names and documentation—it won’t find these products. With value indexing, the Intelligent Context Engine indexes the actual values. When a user submits a natural language query, the engine identifies fields with values that match the query, then uses these retrieved fields to help an agent construct a query with the correct filter value—finding “Running Shoes” and “Athletic Apparel” without exact string matching.

When to Use Value Indexing

Use #(index_values) on:
  • Names and titles - Product names, customer names, program titles
  • Categorical values - Status codes, types, categories
  • Lookup values - Region names, department names, brand names
Skip value indexing for:
  • Numeric fields (amounts, counts, IDs)
  • Timestamps and dates
  • Fields with millions of unique values (diminishing returns)

Example: Well-Documented Model

source: orders is table('sales.orders') {
  primary_key: order_id

  join_one: customers is table('sales.customers') on customer_id
  join_one: products is table('catalog.products') on product_id

  dimension:
    #(doc) Date the order was placed
    order_date is created_at::date

    #(doc) Order status: pending, processing, shipped, delivered, cancelled
    #(index_values) n=-1
    status is order_status

    #(doc) Product category from the catalog
    #(index_values) n=50
    category is products.category

    #(doc) Customer's geographic region
    #(index_values) n=20
    region is customers.region

  measure:
    #(doc) Total number of orders
    order_count is count()

    #(doc) Total revenue in USD
    total_revenue is sum(amount)

    #(doc) Average revenue per order in USD
    avg_order_value is total_revenue / order_count

    #(doc) Percentage of orders that were cancelled
    cancellation_rate is count() { where: status = 'cancelled' } / order_count * 100

  view:
    #(doc) Monthly revenue trend with order counts
    monthly_revenue is {
      group_by: order_date.month
      aggregate: total_revenue, order_count
    }
}

Next Steps