Skip to main content

Overview

Calculated Attributes allow you to write formulas using JSONLogic for creating attributes with dynamic values calculated on the fly. A calculated attribute has access to all Catalog Attributes and the raw underlying data from Shopify prior to transformation and indexing.

Derive builder

The Derive builder is the default option in the Value Formula section when creating or editing a calculated attribute. It provides a visual interface for the most common use case: deriving an attribute value from another attribute using mapping rules. Use the Derive builder when you want to map values from a source attribute (such as tags or a metafield) to new output values without writing JSONLogic manually. For example, you could derive a “Season” attribute from product tags by mapping tag values like “lightweight” and “breathable” to “Summer”, and “insulated” and “thermal” to “Winter”. How to use:
1

Select a source attribute

Choose any indexed attribute from the Source Attribute dropdown. This is the attribute whose values you want to map from (for example, tags).
2

Define mapping rules

Each rule maps one or more source values to an output value:
  • Match type — Choose how to compare against the source value: Contains, Equals, Starts with, or Ends with.
  • Match values — Select one or more values to match against. Multiple values within a single rule use OR logic (a match on any value triggers the rule).
  • Output value — Enter the derived value to assign when the rule matches.
Click + Add rule to add additional rules. Rules are evaluated top to bottom, and the first matching rule wins.
3

Save the attribute

Once your rules are configured, save the attribute. The system automatically recalculates all products in the background.
Key behaviors:
  • Case insensitive — All matching is case insensitive by default. “Summer” and “summer” are treated the same.
  • First match wins — Rules are evaluated in order from top to bottom. Once a rule matches, its output value is used and remaining rules are skipped.
  • Default value — When no rule matches, the attribute is excluded from the product’s calculated object entirely. It will not appear in API responses for that product.
  • Null and empty exclusion — Calculated attributes that evaluate to null or an empty string are automatically excluded from the product data and will not appear in API responses or facet results.
  • Full compatibility — The Derive builder generates standard JSONLogic behind the scenes. You can switch to the Builder tab at any time to view or edit the raw formula.
If you need more complex logic than the Derive builder supports (such as arithmetic operations or multi-attribute conditions), switch to the Builder tab to write JSONLogic directly, or use the Generate with AI feature.

Automatic product recalculation

When you create a new calculated attribute or update an existing calculated attribute’s logic, the system automatically recalculates all products in your catalog in the background. This ensures that your calculated attribute values are immediately applied across your entire product catalog without requiring manual intervention. During recalculation, any calculated attribute that evaluates to null or an empty string is automatically excluded from the product. If a previously stored attribute now evaluates to null or empty, it is removed from the product’s calculated data and from any associated facet values.
Recalculation is triggered only when you create a calculated attribute or modify its logic field. Updates to other fields (like nickname or filterable settings) do not trigger recalculation.

Data access in calculated attributes

Calculated attributes can access two types of data:
  • Catalog Attributes: Use _attribute:{attribute_code} to reference existing catalog attributes. For example, _attribute:price_range.from or _attribute:published_at.
  • Raw Data: Use _raw:raw.{path} to access raw underlying Shopify data before transformation. Use dot notation for nested properties. For example, _raw:raw.variants or _raw:raw.featured_media.

AI-powered calculated attributes

You can use AI to generate and understand calculated attributes without writing JSONLogic manually:

Generate with AI

The “Generate with AI” feature allows you to describe what you want to calculate in natural language, and the system will automatically generate the JSONLogic expression for you. How to use:
  1. Go to AttributesCreate new calculated attribute
  2. Click the Generate with AI button next to “Value Formula”
  3. Enter a natural language description of what you want to calculate (minimum 10 characters)
    • Example: “Calculate the discount percentage from compare_at_price to current price”
    • Example: “Count the total number of variants”
    • Example: “Calculate days since published”
  4. Click Generate to start the AI generation process
  5. Monitor real-time progress updates as the AI generates and validates the expression
  6. Review the generated JSONLogic in the preview
  7. Click Apply to Form to use the generated expression
Generation Process: The AI generation uses a 3-attempt retry mechanism with validation:
  • Attempt 1: Initial generation based on your description
  • Attempts 2-3: If validation fails, the AI receives error feedback and attempts to correct the expression
  • Real-time updates: WebSocket events broadcast progress (generating → retrying → completed/failed)
  • Validation: Each generated expression is validated for correct JSONLogic syntax and proper dependency prefixes
The AI has access to your store’s specific attributes (metafields, named tags, options, variants) and will generate expressions that reference the actual data available in your catalog.

Explain with AI

The “Explain with AI” feature provides human-readable explanations of existing JSONLogic expressions, making it easier to understand what a calculated attribute does. How to use:
  1. Create or edit a calculated attribute with JSONLogic
  2. Scroll to the “What does this formula do?” section below the formula builder
  3. Click Explain with AI
  4. Review the plain-language explanation of your formula
Example explanations:
  • JSONLogic: {"/": [{"-": [{"var": "_attribute:compare_at_price"}, {"var": "_attribute:price"}]}, {"var": "_attribute:compare_at_price"}]}
  • Explanation: “Calculates the discount percentage by comparing the original price to the current selling price. For example, if a product was 100andisnow100 and is now 75, this would return 0.25 (25% off).”
Use “Explain with AI” to document complex formulas or understand calculated attributes created by other team members.

Platform default calculated attributes

The following calculated attributes are available by default in the Layers platform:
Description: Ratio between total number of variants and their availability status.
{
  "/": [
    {
      "reduce": [
        {
          "map": [
            { "var": "_raw:raw.variants" },
            { "if": [ { "var": "available" }, 1, 0 ] }
          ]
        },
        { "+": [ { "var": "accumulator" }, { "var": "current" } ] },
        0
      ]
    },
    { "count": { "var": "_raw:raw.variants" } }
  ]
}
Description: The number of days since the product became available, based on the imported Published At for the product. If no available date has been imported, the system uses the date the product was created.
{
  "daysSince": {
    "parseDate": {
      "or": [
        { "var": ["_attribute:published_at", null] },
        { "var": ["_attribute:created_at", null] }
      ]
    }
  }
}
Description: If the product has a featured image.
{
  "!!": {
    "var": "_raw:raw.featured_media"
  }
}
Description: The age of the most recently created variant.
{
  "daysSince": {
    "reduce": [
      {
        "map": [
          {
            "var": "_raw:raw.variants"
          },
          {
            "parseDate": {
              "var": "created_at"
            }
          }
        ]
      },
      {
        "if": [
          {
            "or": [
              {
                "==": [
                  {
                    "var": "accumulator"
                  },
                  null
                ]
              },
              {
                ">": [
                  {
                    "var": "current"
                  },
                  {
                    "var": "accumulator"
                  }
                ]
              }
            ]
          },
          {
            "var": "current"
          },
          {
            "var": "accumulator"
          }
        ]
      },
      null
    ]
  }
}
Description: If price_range.from != price_range.to.
{
  "!==": [
    {
      "var": "_attribute:price_range.from"
    },
    {
      "var": "_attribute:price_range.to"
    }
  ]
}
For a comprehensive guide to JSONLogic operators and how to write calculated attribute formulas, see JSONLogic Operators.

Additional calculated attribute recipes

Beyond the platform defaults, you can create custom calculated attributes for specific business needs:
Description: The percentage discount calculated from compare_at_price to current price. Returns 0 if no discount is available.Use Case: Sort products by discount amount or filter for products on sale. Create “Biggest Discounts” collections or exclude heavily discounted items from premium merchandising.
{
  "if": [
    {
      "and": [
        { "var": "_attribute:price_range.to" },
        {
          ">": [
            { "var": "_attribute:price_range.to" },
            { "var": "_attribute:price_range.from" }
          ]
        }
      ]
    },
    {
      "*": [
        {
          "/": [
            {
              "-": [
                { "var": "_attribute:price_range.to" },
                { "var": "_attribute:price_range.from" }
              ]
            },
            { "var": "_attribute:price_range.to" }
          ]
        },
        100
      ]
    },
    0
  ]
}
Attributes: Filterable, Sortable | Value Type: Number (percentage)Example: A product with compare_at_price of 100andcurrentpriceof100 and current price of 75 has a discount percentage of 25.
Description: The total number of variants for this product. Useful for filtering or sorting by product complexity.Use Case: Identify products with many options (high variant count) or single-variant products. Filter out products with too many variants from certain collections.
{
  "count": [{ "var": "_raw:raw.variants" }]
}
Attributes: Filterable, Sortable | Value Type: Number (count)Example: A t-shirt available in 5 colors and 4 sizes (20 combinations) has a variant count of 20.
Description: Average profit margin across variants, calculated as (price - cost) / price for each variant with cost data. Excluded from the product if no variants have cost information (the formula evaluates to null).Use Case: Sort products by profitability or filter for high-margin items. Create “Best Margin” collections for merchandising or exclude low-margin products from promotional campaigns.
{
  "if": [
    [
      {
        ">": [
          {
            "reduce": [
              {
                "map": [
                  { "var": "_raw:raw.variants" },
                  {
                    "if": [
                      {
                        "and": [
                          { "!=": [{ "var": "cost" }, null] },
                          { ">": [{ "var": "price" }, 0] }
                        ]
                      },
                      1,
                      0
                    ]
                  }
                ]
              },
              {
                "+": [
                  { "var": "accumulator" },
                  { "var": "current" }
                ]
              },
              0
            ]
          },
          0
        ]
      }
    ],
    {
      "/": [
        {
          "reduce": [
            {
              "map": [
                { "var": "_raw:raw.variants" },
                {
                  "if": [
                    {
                      "and": [
                        { "!=": [{ "var": "cost" }, null] },
                        { ">": [{ "var": "price" }, 0] }
                      ]
                    },
                    {
                      "/": [
                        {
                          "-": [
                            { "var": "price" },
                            { "var": "cost" }
                          ]
                        },
                        { "var": "price" }
                      ]
                    },
                    0
                  ]
                }
              ]
            },
            {
              "+": [
                { "var": "accumulator" },
                { "var": "current" }
              ]
            },
            0
          ]
        },
        {
          "reduce": [
            {
              "map": [
                { "var": "_raw:raw.variants" },
                {
                  "if": [
                    {
                      "and": [
                        { "!=": [{ "var": "cost" }, null] },
                        { ">": [{ "var": "price" }, 0] }
                      ]
                    },
                    1,
                    0
                  ]
                }
              ]
            },
            {
              "+": [
                { "var": "accumulator" },
                { "var": "current" }
              ]
            },
            0
          ]
        }
      ]
    },
    null
  ]
}
Attributes: Filterable, Sortable | Value Type: Number (decimal)Example: A product with two variants (price=10,cost=10, cost=5 and price=20,cost=20, cost=10) has an average margin of 0.5 (50%).

See also