Back to Top

Sort Category Products by Custom Price in Magento 2

Updated 23 September 2025

category-sort-bycustom-price-image

Introduction

In Magento 2, you may need to sort products by custom price instead of default options like name or base price.

This can be useful for variation pricing, promotional campaigns, or external pricing rules.

Consequently, by extending Elasticsearch, you can index custom prices and use them directly in sorting.

👉 If you’re looking for filtering instead of sorting, check our guide on filtering category products by specific IDs.

Searching for an experienced
Magento 2 Company ?
Find out More

Step 1: Understand the Flow

Magento uses Elasticsearch to index product data in JSON documents.

Therefore, works only on fields that already exist in these documents.

To enable sorting by custom price, we need to:

  • Add custom price fields in Elasticsearch via ProductDataMapper.
  • Map field names via Resolver\Price.
  • Finally modify the sort builder via a Sort plugin.

For more about Magento’s Elasticsearch setup, see Magento DevDocs.

Step 2: Add Custom Price Fields to Elasticsearch

Create a plugin for:

\Magento\Elasticsearch\Model\Adapter\BatchDataMapper\ProductDataMapper::map()

This plugin injects custom prices during indexing:

$result[$productId]['custom_price_b' . $variationId] = $price;

Now, documents may look like:

{
  "custom_price_b1": 23.00,
  "custom_price_b2": 25.00
}

Step 3: Resolve Field Names for Sorting

Magento resolves price fields dynamically through:

\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price

Create a plugin for getFieldName() so Magento can detect your custom price fields.

This ensures that when you pass a variation ID, the correct custom price field is used.

Step 4: Modify the Sort Query

Sorting queries are built in:

\Magento\Elasticsearch\SearchAdapter\Query\Builder\Sort::getSort()

With a plugin, you can override it to point sorting toward your custom field:

return [
  [$fieldName => ['order' => $sortRequest['direction'] ?? 'asc']]
];

Example query:

"sort": [
  { "custom_price_b1": { "order": "asc" } }
]

Bonus: Sorting Multiple Prices with a Painless Script

If, however, a product has multiple prices?

In this case, Elasticsearch supports painless scripts to handle advanced sorting logic.

You can write a script to return the lowest price across all variations:

"_script": {
  "type": "number",
  "order": "asc",
  "script": {
    "lang": "painless",
    "params": { "fields": ["custom_price_b1", "custom_price_b2"], "missing": 1.0e15 },
    "source": "double best = Double.POSITIVE_INFINITY; for (String f : params.fields) { if (doc.containsKey(f) && doc[f].size() > 0) { double v = doc[f].value; if (v < best) best = v; } } return best;"
  }
}

For details, check the Elasticsearch sort documentation.

Step 5: Reindex and Test

After making changes, run these commands:

bin/magento setup:upgrade
bin/magento indexer:reindex
bin/magento cache:flush

As a result, now category pages can sort products by single or multiple custom prices.

Conclusion

To sort products by custom price in Magento 2 allows you to control category listings beyond the default options.

Moreover, by enriching Elasticsearch, mapping fields, and customizing the sort query, you can implement business-driven pricing logic.

👉 You can also learn how to filter products by specific IDs for even more control over category listings.

For advanced features, explore Magento DevDocs and Elasticsearch official docs.

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home