Ranking Fields

Ranking Fields

These fields control how products are ranked and sorted in search results and category listings. They are used by the Ranking Mix feature.

Source Fields

Provide these fields in your import data to enable ranking:

FieldTypeDescriptionUsed For
soldamountfloatNumber of units soldSales-based ranking
ratingfloatProduct rating (e.g., 1-5)Rating-based ranking
insertdateProduct creation dateNewness ranking
profit_marginfloatProfit margin percentageMargin-based ranking
stockintegerStock quantityOut-of-stock demotion

Example Import

{
  "id": "product-123",
  "type": "product",
  "title": "Blue T-Shirt",
  "soldamount": 150,
  "rating": 4.5,
  "insert": "2024-01-15",
  "profit_margin": 35.5,
  "stock": 100
}

Normalized Boost Fields

When using the Persistence Layer, source fields are automatically normalized to a 0-1 scale:

Normalized FieldSourceDescription
mak_boost_norm_insertinsertNewness score (newer = higher)
mak_boost_norm_soldsoldamountSales performance
mak_boost_norm_ratingratingCustomer rating
mak_boost_norm_revenuesoldamount × priceRevenue generated
mak_boost_norm_profit_marginprofit_marginProfit margin
mak_boost_norm_basketAnalyticsCart additions
mak_boost_norm_viewAnalyticsProduct views

Normalization Formula

normalized = (log(value + 1) - log(min + 1)) / (log(max + 1) - log(min + 1))

This logarithmic normalization ensures:

  • All values are scaled between 0 and 1
  • Outliers don't dominate rankings
  • Relative differences are preserved

Note: Without the Persistence Layer, normalized fields are not automatically calculated. See the next section for how to provide them yourself, or rely on the source fields and the default ranking.

Providing Normalized Boosts Manually

If you import directly (NDJSON, API push) without the Persistence Layer and want to use the Ranking Mix, you have two options:

  1. Pre-calculate the boost fields yourself and ship them in your feed alongside the source fields. This is the recommended path when you want full control over the Ranking Mix.
  2. Only ship the source fields (soldamount, rating, insert, profit_margin, stock). The Ranking Mix entries that depend on mak_boost_norm_* will then be inactive, but the default search ranking still works.

Field list and value range

Provide these fields on the parent product document (type: product, internal datatype: makaira-productgroup) — not on the variant (type: variant / datatype: makaira-product). The Ranking Mix rescore is applied at the productgroup level. All values must be floats in the range 0.01.0, where 1.0 is the strongest boost and 0.0 the weakest.

FieldSuggested inputHigher value means
mak_boost_norm_insertProduct creation dateNewer product
mak_boost_norm_soldUnits soldMore sales
mak_boost_norm_ratingCustomer ratingBetter rated
mak_boost_norm_revenuesoldamount × priceMore revenue
mak_boost_norm_profit_marginProfit marginHigher margin

mak_boost_norm_basket and mak_boost_norm_view are filled by Makaira analytics — do not set them manually.

Recommended normalization

The same logarithmic normalization that the Persistence Layer applies works well for self-normalized feeds because it keeps outliers in check:

normalized = (log(value + 1) - log(min + 1)) / (log(max + 1) - log(min + 1))

min and max are the minimum and maximum of the metric across your catalog (e.g. across all products for soldamount). A simple Min-Max normalization ((value - min) / (max - min)) also works if the metric does not have heavy outliers.

For mak_boost_norm_insert invert the age so that newer products end up closer to 1.0, e.g.:

age_days  = today - insert_date (in days)
normalized = 1 - min(age_days, max_age) / max_age   // clamp very old products to 0

Example

{
  "id": "product-123",
  "type": "product",
  "parent": "",
  "soldamount": 150,
  "rating": 4.5,
  "insert": "2024-01-15",
  "profit_margin": 35.5,
  "mak_boost_norm_sold": 0.78,
  "mak_boost_norm_rating": 0.90,
  "mak_boost_norm_insert": 0.42,
  "mak_boost_norm_revenue": 0.65,
  "mak_boost_norm_profit_margin": 0.71
}
💡

You can ship both the source fields and the mak_boost_norm_* fields. The source fields are still useful for sorting (Sort by sold amount) and other UI features.

Ranking Mix Configuration

The Ranking Mix in the admin UI maps to these fields:

Admin UI NameElasticsearch FieldSource Data
Newmak_boost_norm_insertinsert date
Soldmak_boost_norm_soldsoldamount
Basketmak_boost_norm_basketAnalytics
Viewmak_boost_norm_viewAnalytics
Revenuemak_boost_norm_revenueCalculated
Ratingmak_boost_norm_ratingrating
Profit Marginmak_boost_norm_profit_marginprofit_margin

Stock-Based Ranking

The stock field has a special use: when "Out of stock at the end" is enabled in the Ranking Mix:

  • Products with stock = 0 are pushed to the bottom of results
  • Their search score is multiplied by 0
  • This applies to both search and category listings

How It Works

Product A: stock = 100, score = 0.8  → Final: 0.8 (top)
Product B: stock = 50,  score = 0.6  → Final: 0.6 (middle)
Product C: stock = 0,   score = 0.9  → Final: 0.0 (bottom)

Group-Specific Stock

Stock can be overridden per customer group:

{
  "id": "product-123",
  "stock": 100,
  "groups": {
    "wholesale": {
      "stock": 1000
    },
    "retail": {
      "stock": 50
    }
  }
}

Machine Learning Boost Fields

Additional boost fields from ML and analytics:

Field PatternDescription
mak_boost_{key}ML-derived boost value
mak_boost_category_{id}Category-specific boost
mak_boost_manufacturer_{id}Manufacturer-specific boost

These are populated automatically when Machine Learning features are enabled.

Best Practices

  1. Provide source data - Include soldamount, rating, insert, and profit_margin for full ranking capabilities.

  2. Keep stock updated - The stock field directly affects ranking when "out of stock at the end" is enabled.

  3. Use the Persistence Layer - For automatic normalization and consistent boost calculations.

  4. Monitor analytics - basket and view boosts require tracking integration.