Indexes: Boosting


  • When querying with some filtering conditions,
    a basic score is calculated for each document in the results by the underlying engine.

  • Providing a boost value to some fields allows you to prioritize the resulting documents.
    The boost value is integrated with the basic score, making the document rank higher.
    Automatic ordering of the results by the score is configurable.

  • Boosting can be achieved in the following ways:

    • At query time:
      Apply a boost factor to searched terms at query time - see article Boost search results.

    • Via index definition:
      Apply a boost factor in your index definition - as described in this article.

  • In this page:


Assign a boost factor to an index-field

Applying a boost value to an index-field allows you to prioritize matching documents based on an index-field.


The index:

public class Orders_ByCountries_BoostByField : AbstractIndexCreationTask<Order>
{
    public class IndexEntry
    {
        // Index-field 'ShipToCountry' will be boosted in the map definition below
        public string ShipToCountry { get; set; }
        public string CompanyCountry { get; set; }
    }
    
    public Orders_ByCountries_BoostByField()
    {
        Map = orders => from order in orders
            let company = LoadDocument<Company>(order.Company)
            
            // Note: with current server version,
            // use 'select new' instead of 'select new IndexEntry' for compilation
            select new 
            {
                // Boost index-field 'ShipToCountry':
                // * Use method 'Boost', pass a numeric value to boost by 
                // * Documents that match the query criteria for this field will rank higher
                ShipToCountry = order.ShipTo.Country.Boost(10), 
                CompanyCountry = company.Address.Country
            };
    }
}
public class Orders_ByCountries_BoostByField_JS : AbstractJavaScriptIndexCreationTask
{
    public Orders_ByCountries_BoostByField_JS()
    {
        Maps = new HashSet<string>()
        {
            @"map('orders', function(order) {
                let company = load(order.Company, 'Companies')
                return {
                    ShipToCountry: boost(order.ShipTo.Country, 10),
                    CompanyCountry: company.Address.Country
                };
            })"
        };
    }
}
The query:

List<Order> orders = session
     // Query the index    
    .Query<Orders_ByCountries_BoostByField.IndexEntry, Orders_ByCountries_BoostByField>()
    .Where(x => x.ShipToCountry == "Poland" || x.CompanyCountry == "Portugal")
    .OfType<Order>()
    .ToList();

// Because index-field 'ShipToCountry' was boosted (inside the index definition),
// then documents containing 'Poland' in their 'ShipTo.Country' field will get a higher score than
// documents containing a company that is located in 'Portugal'.
List<Order> orders = await asyncSession
     // Query the index    
    .Query<Orders_ByCountries_BoostByField.IndexEntry, Orders_ByCountries_BoostByField>()
    .Where(x => x.ShipToCountry == "Poland" || x.CompanyCountry == "Portugal")
    .OfType<Order>()
    .ToListAsync();

// Because index-field 'ShipToCountry' was boosted (inside the index definition),
// then documents containing 'Poland' in their 'ShipTo.Country' field will get a higher score than
// documents containing a company that is located in 'Portugal'.
List<Order> orders = session.Advanced
     // Query the index 
    .DocumentQuery<Orders_ByCountries_BoostByField.IndexEntry, Orders_ByCountries_BoostByField>()
    .WhereEquals(x => x.ShipToCountry, "Poland")
    .OrElse()
    .WhereEquals(x => x.CompanyCountry, "Portugal")
    .OfType<Order>()
    .ToList();

// Because index-field 'ShipToCountry' was boosted (inside the index definition),
// then documents containing 'Poland' in their 'ShipTo.Country' field will get a higher score than
// documents containing a company that is located in 'Portugal'.
from index "Orders/ByCountries/BoostByField"
where ShipToCountry == "poland" or CompanyCountry == "portugal"

Assign a boost factor to the index-entry

Applying a boost value to the whole index-entry allows you to prioritize matching documents by content from the document.


The index:

public class Orders_ByCountries_BoostByIndexEntry : AbstractIndexCreationTask<Order>
{
    public class IndexEntry
    {
        public string ShipToCountry { get; set; }
        public string CompanyCountry { get; set; }
    }
    
    public Orders_ByCountries_BoostByIndexEntry()
    {
        Map = orders => from order in orders
            let company = LoadDocument<Company>(order.Company)
            
            select new IndexEntry()
            {
                ShipToCountry = order.ShipTo.Country,
                CompanyCountry = company.Address.Country
            }
            // Boost the whole index-entry:
            // * Use method 'Boost'
            // * Pass a document-field that will set the boost level dynamically per document indexed.  
            // * The boost level will vary from one document to another based on the value of this field.
           .Boost((float) order.Freight);
    }
}
public class Orders_ByCountries_BoostByIndexEntry_JS : AbstractJavaScriptIndexCreationTask
{
    public Orders_ByCountries_BoostByIndexEntry_JS()
    {
        Maps = new HashSet<string>()
        {
            @"map('orders', function(order) {
                let company = load(order.Company, 'Companies')
                return boost({
                    ShipToCountry: order.ShipTo.Country,
                    CompanyCountry: company.Address.Country
                }, order.Freight)
            })"
        };
    }
}
The query:

List<Order> orders = session
     // Query the index  
    .Query<Orders_ByCountries_BoostByIndexEntry.IndexEntry, Orders_ByCountries_BoostByIndexEntry>()
    .Where(x => x.ShipToCountry == "Poland" || x.CompanyCountry == "Portugal")
    .OfType<Order>()
    .ToList();

// The resulting score per matching document is affected by the value of the document-field 'Freight'. 
// Documents with a higher 'Freight' value will rank higher.
List<Order> orders = await asyncSession
     // Query the index  
    .Query<Orders_ByCountries_BoostByIndexEntry.IndexEntry, Orders_ByCountries_BoostByIndexEntry>()
    .Where(x => x.ShipToCountry == "Poland" || x.CompanyCountry == "Portugal")
    .OfType<Order>()
    .ToListAsync();

// The resulting score per matching document is affected by the value of the document-field 'Freight'. 
// Documents with a higher 'Freight' value will rank higher.
List<Order> orders = session.Advanced
     // Query the index  
    .DocumentQuery<Orders_ByCountries_BoostByIndexEntry.IndexEntry, Orders_ByCountries_BoostByIndexEntry>()
    .WhereEquals(x => x.ShipToCountry, "Poland")
    .OrElse()
    .WhereEquals(x => x.CompanyCountry, "Portugal")
    .OfType<Order>()
    .ToList();

// The resulting score per matching document is affected by the value of the document-field 'Freight'. 
// Documents with a higher 'Freight' value will rank higher.
from index "Orders/ByCountries/BoostByIndexEntry"
where ShipToCountry == "poland" or CompanyCountry == "portugal"

Automatic score-based ordering

  • By default, whenever boosting is involved, either via a dynamic query or when querying an index that has a boosting factor in its definition, the results will be automatically ordered by the score.

  • This behavior can be modified using the OrderByScoreAutomaticallyWhenBoostingIsInvolved
    configuration key.

  • Refer to section Get resulting score to learn how to retrieve the calculated score of each result.