Extending the Plugin
For most use cases, the built-in boost types are sufficient. This guide covers creating custom boost types for specialized requirements.
Architecture Overview
The plugin uses a simple class hierarchy:
1BoostConfiguration (abstract) — defines how boosts are organized2└── CustomBoostConfiguration — user-configurable list of boosts34Boost (abstract)5├── IndexBoost (abstract) — for field-based boosts6│ ├── ExactMatchBoost7│ ├── PartialMatchBoost8│ ├── StartsWithBoost9│ ├── NewestBoost10│ └── OldestBoost11└── TypeBoost (abstract) — for content type-based boosts12├── ContentTypeBoost13└── SemanticMatchBoost
There are two main extension points:
- BoostConfiguration — Controls how boosts are organized and applied (e.g., curated presets vs. user-defined lists)
- Boost — Individual boost rules that modify query relevance
Creating a Custom Boost
Option 1: Extend IndexBoost
Use IndexBoost when your boost operates on an indexed field. This gives you the field selector UI automatically.
167/**8* Boosts results where the selected field contains the query as a substring, using case-insensitive matching.9*/10@Recordable.DisplayName("Contains Match")11public class ContainsMatchBoost extends IndexBoost {1213@Override14public void updateQuery(Search search, Query<?> query) {15String queryString = search.getQueryString();16if (StringUtils.isBlank(queryString)) {17return;18}1920String index = getIndex();21if (StringUtils.isBlank(index)) {22return;23}2425// Boost results where the field contains the query string26query.sortRelevant(getBoost(), index + " matchesAll ?", queryString.toLowerCase());27}28}
Key points:
- Extend
IndexBoostto inherit the field selector UI - Use
getIndex()to get the selected field name - Use
getBoost()to get the calculated boost factor from the weight - Override
getIndexFieldType()to filter available fields (default is"text", use"date"for date fields)
Option 2: Extend TypeBoost
Use TypeBoost when your boost operates on a content type. This gives you the content type selector UI.
167/**8* Boosts results of the selected content type only when the search query is longer than a specified minimum length.9*/10@Recordable.DisplayName("Long Query Type Boost")11public class LongQueryTypeBoost extends TypeBoost {1213@Recordable.Minimum(1)14private int minimumQueryLength = 3;1516public int getMinimumQueryLength() {17return minimumQueryLength;18}1920public void setMinimumQueryLength(int minimumQueryLength) {21this.minimumQueryLength = minimumQueryLength;22}2324@Override25public void updateQuery(Search search, Query<?> query) {26String queryString = search.getQueryString();2728// Only apply boost for queries meeting minimum length29if (queryString == null || queryString.length() < minimumQueryLength) {30return;31}3233ObjectType objectType = getContentObjectType();34if (objectType == null) {35return;36}3738query.sortRelevant(getBoost(), "_type = ?", objectType.findConcreteTypes());39}40}
Key points:
- Extend
TypeBoostto inherit the content type selector UI - Use
getContentObjectType()to get the selectedObjectType - Add custom fields with standard Dari annotations
Option 3: Extend Boost Directly
For completely custom logic that doesn't fit the field or type patterns, extend Boost directly.
156/**7* Boosts results that are marked as "featured" in the CMS. This boost applies regardless of the search query.8*/9@Recordable.DisplayName("Featured Content")10public class FeaturedContentBoost extends Boost {1112@Override13public void updateQuery(Search search, Query<?> query) {14// Boost any content where the 'featured' field is true15query.sortRelevant(getBoost(), "featured = ?", true);16}1718@Override19public String getLabel() {20return "Featured Content (" + getWeight() + ")";21}22}
Key points:
- You're responsible for all configuration fields and UI
- Override
getLabel()to provide a meaningful display name - The boost automatically appears in the boost type dropdown
Creating a Custom BoostConfiguration
While CustomBoostConfiguration lets users build their own boost lists, you can extend BoostConfiguration to create curated presets with hardcoded boost rules. This is useful for:
- Providing optimized configurations for specific use cases (e.g., "News Site", "E-Commerce")
- Enforcing consistent boost rules across sites
- Simplifying configuration for non-technical users
Example: Curated News Configuration
156/**7* Pre-configured boost settings optimized for news sites. Prioritizes recent content and exact headline matches.8*/9@Recordable.DisplayName("News Site (Optimized)")10public class NewsBoostConfiguration extends BoostConfiguration {1112@Minimum(0)13@Maximum(100)14private int weightMultiplier = 50;1516@Override17public void updateQuery(Search search, Query<?> query) {18String queryString = search.getQueryString();19double baseBoost = calculateBoost(weightMultiplier);2021// Strong boost for exact headline matches22query.sortRelevant(baseBoost * 2, "headline = ?", queryString);2324// Moderate boost for partial headline matches25for (String term : queryString.split("\\s+")) {26query.sortRelevant(baseBoost, "headline matches ?", "*" + term + "*");27}2829// Boost recent content (within last 7 days gets highest boost)30query.sortNewest(baseBoost * 1.5, "cms.content.publishDate");31}3233private double calculateBoost(int weight) {34return Math.pow(10, weight / 10.0);35}3637public int getWeightMultiplier() {38return weightMultiplier;39}4041public void setWeightMultiplier(int weightMultiplier) {42this.weightMultiplier = weightMultiplier;43}44}
Key points:
- Extend
BoostConfigurationdirectly - Override
updateQuery()to apply your hardcoded boost logic - Use
@Recordable.DisplayNameto give it a friendly name in the dropdown - Optionally add configurable fields to allow some customization (like the weight multiplier in the example)
When to Use Custom BoostConfiguration
| Use Case | Approach |
|---|---|
| Users need full control over boost rules | Use built-in CustomBoostConfiguration |
| Provide optimized presets users can select | Create custom BoostConfiguration subclasses |
| Mix of preset + customization | Create custom BoostConfiguration with configurable fields |
| Enforce specific boost rules programmatically | Create custom BoostConfiguration with hardcoded logic |
Key APIs
Query Methods
The Query class provides several methods for applying boosts:
1// Boost by a condition2query.sortRelevant(boostFactor, "field = ?", value);34// Boost by date (newer first)5query.sortNewest(boostFactor, "dateField");67// Boost by date (older first)8query.sortOldest(boostFactor, "dateField");
Search Context
The Search object provides access to:
1search.getQueryString() // The raw search query entered by the user
Weight Conversion
The getBoost() method converts the 0-100 weight to a logarithmic scale:
- Weight 0 = boost factor 1.0
- Weight 50 = boost factor ~1,000
- Weight 100 = boost factor ~1 billion
Registration
Custom boosts and configurations are automatically discovered and appear in the CMS UI. Just ensure your class:
- Extends
Boost,IndexBoost,TypeBoost, orBoostConfiguration - Has the
@Recordable.DisplayNameannotation for a friendly name