Skip to content

Instantly share code, notes, and snippets.

@sitefinitySDK
Created May 21, 2025 07:50
Show Gist options
  • Save sitefinitySDK/b70c8c416590bf3f1be659e441d83733 to your computer and use it in GitHub Desktop.
Save sitefinitySDK/b70c8c416590bf3f1be659e441d83733 to your computer and use it in GitHub Desktop.
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Queries;
using Lucene.Net.Search;
using System;
using Telerik.Sitefinity.Publishing;
namespace SitefinityWebApp.Documentation.Samples.Search
{
/// <summary>
/// Default Sitefinity inheritor for Lucene CustomScoreQuery
/// </summary>
public class SitefinityCustomScoreQuery : CustomScoreQuery
{
/// <summary>
/// Initializes a new instance of the <see cref="SitefinityCustomScoreQuery"/> class.
/// </summary>
/// <param name="subQuery">The Lucene query</param>
/// <param name="excludeContentAge">A value indicating whether the content age should be included in the score calculation</param>
public SitefinityCustomScoreQuery(Query subQuery, bool excludeContentAge) : base(subQuery)
{
this.excludeContentAge = excludeContentAge;
}
/// <inheritdoc />
protected override CustomScoreProvider GetCustomScoreProvider(AtomicReaderContext reader)
{
return new CustomizedScoreProvider(reader, this.excludeContentAge);
}
/// <summary>
/// The custom score provider for <see cref="SitefinityCustomScoreQuery"/>
/// </summary>
protected class CustomizedScoreProvider : CustomScoreProvider
{
/// <summary>
/// Initializes a new instance of the <see cref="CustomizedScoreProvider"/> class.
/// </summary>
/// <param name="reader">The index reader</param>
/// <param name="excludeContentAge">A value indicating whether the content age should be included in the score calculation</param>
public CustomizedScoreProvider(AtomicReaderContext reader, bool excludeContentAge) : base(reader)
{
this.excludeAge = excludeContentAge;
}
/// <inheritdoc />
public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
{
var baseScore = base.CustomScore(doc, subQueryScore, valSrcScores);
if (this.excludeAge)
return baseScore;
double boost = 1;
var currentDocument = this.m_context.Reader.Document(doc);
var dateFieldValue = currentDocument.Get(PublishingConstants.FieldLastModified);
if (!string.IsNullOrEmpty(dateFieldValue))
{
var now = DateTime.UtcNow;
var date = DateTools.StringToDate(dateFieldValue);
var age = (int)(now - date).TotalDays;
boost = this.CalculateBoost(age);
}
var adjustedScore = baseScore * boost;
return (float)adjustedScore;
}
/// <summary>
/// Calculates the boost, based on the content's age
/// </summary>
/// <param name="days">Content's age in days</param>
/// <returns>The boost</returns>
protected virtual double CalculateBoost(int days)
{
if (days < 0)
days = 0;
double boostFactor = 100;
double maxRampFactor = 3;
double curveAdjustmentFactor = 5;
return Math.Pow(boostFactor / (maxRampFactor + days), 1 / curveAdjustmentFactor);
}
private bool excludeAge = false;
}
private bool excludeContentAge;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment