Hi Vidar
Boosting during indexing is not relevant here.
Here are my current status. Some article types already have som boosting and I have reduced their boosting by a huge amount. Search words are split up and fuzzy and boosting is applied to each word.
After that I want to apply the custom query boosting for newest articles. What is the correct way to do this?
Right now all the boosting logic is hidden in a class (MyCustomScoreQuery) derived from Lucene.Net.Search.Function.CustomScoreQuery, as described in the link from the first post. If I use the CustomQuery property I get no results. What happens if I use both BodySearch and CustomQuery.
To make it event more complex, the query is also used in an AdvancedIndexQuery<T>
// escape lucene characters and split into words
var terms = Regex.Replace(search, "([+\\-\\(\\)\\{\\}\\[\\]\"\\^\\~\\*\\?\\:\\\\]|\\&\\&|\\|\\|)", "\\$1")
.Split(' ')
.Where(a => !string.IsNullOrWhiteSpace(a));
search = "" + string.Join(" ", terms.Select(a => a + "~0.7^3.0")) + " " + string.Join(" ", terms.Select(a => a + "*^3.0"));
query.BodySearch = search;
// TODO: boost articles newer than X days ( with this active we get no results )
var q1 = new Lucene.Net.Search.BooleanQuery();
var myCustomSearch = new MyCustomScoreQuery(q1);
query.CustomQuery = myCustomSearch;
var advancedQuery = new AdvancedIndexQuery(query);
advancedQuery.SuggestDifferentSpelling = true;
if (!autoCompleteSearch)
{
advancedQuery.EnableFacetedSearch = true;
advancedQuery.FacetFilterOption = WAF.Engine.Search.Facets.FacetFilterOptions.ShowAllFacetValuesForActiveFacets;
advancedQuery.CustomLuceneFieldsToFacetOn = new List() { "Class" };
if (FacetFilters != null)
advancedQuery.FacetFilters = FacetFilters;
}
SearchResultSet searchResultSet = WAFContext.Session.SearchAdvanced(advancedQuery);
[Serializable]
public class MyCustomScoreQuery : Lucene.Net.Search.Function.CustomScoreQuery
{
public MyCustomScoreQuery(Lucene.Net.Search.Query subQuery) : base(subQuery)
{
}
///
/// The custom score provider for
///
protected class CustomizedScoreProvider : Lucene.Net.Search.Function.CustomScoreProvider
{
///
/// Initializes a new instance of the class.
///
///The index reader
public CustomizedScoreProvider(Lucene.Net.Index.IndexReader reader) : base(reader)
{
}
///
public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
{
var baseScore = base.CustomScore(doc, subQueryScore, valSrcScores);
double boost = 1;
var currentDocument = reader.Document(doc);
var dateFieldValue = currentDocument.Get("LastModified");
if (dateFieldValue != null)
{
var now = DateTime.UtcNow;
var date = DateTime.Parse(dateFieldValue);// DateTools.StringToDate(dateFieldValue);
var age = (int)(now - date).TotalDays;
boost = CalculateBoost(age);
}
var adjustedScore = baseScore * boost;
return (float)adjustedScore;
}
///
/// Calculates the boost, based on the content's age
///
///Content's age in days
/// The boost
protected virtual double CalculateBoost(int days)
{
double boostFactor = 100;
double maxRampFactor = 5;
double curveAdjustmentFactor = 5;
return Math.Pow(boostFactor / (maxRampFactor + days), 1 / curveAdjustmentFactor);
}
}
}