
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.
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.

Be the first to comment.