Hi everyone
I did pretty much what you recommended, DIGY. Thanks - I didn't think of
loading it all into a collection and sorting it, too used to that being
expensive to do (which it is from a DB, but not from Lucene it appears!)
We used a linier (sp?) gradient from the boost. I'd prefer to use a
curve, but this works, and it's easy.
I've appended my code below, incase it's of use for someone else. Some
notes from it:
We deal with an IMetadataDocument, which is really just a wrapper around
the Lucene document's fields, with the score added.
There are a few things (eg CurrentTicks) which are inited twice. This is
because we call them from unit tests.
CalcScore can return the score * [2..0.5]
Hope it's of help to someone!
Thanks!
Nic
/// <summary>
/// Perform a search against the index.
/// </summary>
/// <param name="searchTerms"></param>
/// <returns></returns>
private IList<IMetadataDocument> PerformSearch(string
searchTerms)
{
IndexReader reader = GetIndexReader();
Query query = queryParser.Parse(searchTerms);
Hits hitsFound = searcher.Search(query);
IList<IMetadataDocument> sortedDocuments =
BubbleUpMoreCurrentDocuments(hitsFound);
return sortedDocuments;
}
private long CurrentTicks = DateTime.Now.Ticks;
private long TicksSixMonthsAgo =
DateTime.Now.AddMonths(-6).Ticks;
private IList<IMetadataDocument>
BubbleUpMoreCurrentDocuments(Hits hitsFound)
{
CurrentTicks = DateTime.Now.Ticks;
TicksSixMonthsAgo = DateTime.Now.AddMonths(-6).Ticks;
List<IMetadataDocument> docs = new
List<IMetadataDocument>();
for (int i = 0; i < hitsFound.Length(); i++)
{
docs.Add(InterfaceFromLuceneDocument(hitsFound.Doc(i),
CalcScore(hitsFound.Doc(i).Get("datecreated"), hitsFound.Score(i))));
}
docs.Sort(CompareDocuments);
return docs;
}
private static int CompareDocuments(IMetadataDocument x,
IMetadataDocument y)
{
// note negative values - we want it smalled to biggest
if (x == null)
{
if (y == null)
{
// If x is null and y is null, they're
// equal.
return 0;
}
else
{
// If x is null and y is not null, y
// is greater.
return 1;
}
}
else
{
// If x is not null...
//
if (y == null)
// ...and y is null, x is greater.
{
return -1;
}
else
{
return -x.SearchScore.CompareTo(y.SearchScore);
}
}
}
//Your custom Score Function
public float CalcScore(string FieldValue, float OriginalScore)
{
long fieldTicks = Int64.Parse(FieldValue);
float scoreModifier = 0;
float MinScoreModifier = 0.5f;
float MaxScoreModifier = 2;
if (fieldTicks < TicksSixMonthsAgo)
{
scoreModifier = MinScoreModifier;
} else if (fieldTicks > CurrentTicks)
{
scoreModifier = MaxScoreModifier;
} else
{
long fieldTickOffset = CurrentTicks - fieldTicks;
long tickRange = CurrentTicks - TicksSixMonthsAgo;
// General formula: gradient * x + offset
// gradient = - (range of score (which is 2 to 0.5, so
1.5) / range of ticks ( which is 0..SixMonths)
// x is the field tick offset - how far back our value
is from the current time (or 0 on the X axis)
// offset is the maximum we can go
scoreModifier = (-((
(MaxScoreModifier-MinScoreModifier)/tickRange)*fieldTickOffset)) +
MaxScoreModifier;
}
// if we had 0.5 as the original, things close to now return
close to 2
// and thigns close (or more than) 6 months old return close
to 0.25
return scoreModifier * OriginalScore;
}
-----Original Message-----
From: DIGY [mailto:[EMAIL PROTECTED]
Sent: 16 January 2008 17:47
To: [email protected]
Subject: RE: Bubbling up "newer" records
Hi Nic,
What I meant was something like below
DIGY
<snip>
This e-mail (and any attachments) is confidential and may contain personal
views which are not the views of the BBC unless specifically stated. If you
have received it in error, please delete it from your system. Do not use, copy
or disclose the information in any way nor act in reliance on it and notify the
sender immediately.
Please note that the BBC monitors e-mails sent or received. Further
communication will signify your consent to this
This e-mail has been sent by one of the following wholly-owned subsidiaries of
the BBC:
BBC Worldwide, Registration Number: 1420028 England, Registered Address:
Woodlands, 80 Wood Lane, London W12 0TT
BBC World, Registration Number: 04514407 England, Registered Address:
Woodlands, 80 Wood Lane, London W12 0TT
BBC World Distribution Limited, Registration Number: 04514408, Registered
Address: Woodlands, 80 Wood Lane, London W12 0TT