Stored procedure with a string parameter that will contain a few words.
Table with about 30k rows with a field that will have words
We want to pull the BEST match based on this Ranking (order of importance and if more than one qualify keep testing downward)
- exact match
- full match inside string
- Most words matching
- first word closest to front of string
- Matches with least words left over
- Order of Matches
- Top 1
Here's the some sample data: http://sqlfiddle.com/#!6/c8665/1
Using SQL Azure. Might User Functions be an option for this?
We were using this LINQ code but need to move to a Stored procedure:
public PKB Best(string words)
{
if (string.IsNullOrEmpty(words))
{
words = "pkb-not-found";
}
try
{
var ctx = new MiamiDbContext();
//var allRows = ctx.PKB.ToList();
var allRows = ctx.PKB.Where(x => x.PKBTitle.Contains("$")).ToList();
var max = allRows.Max(x => CountChars(x.PKBTitle, words));
if (max == 0)
{
throw new Exception("No records found");
}
var allMax = allRows.Where(x => CountChars(x.PKBTitle, words) == max).OrderByDescending(x => x.PKBDate).ToList();
return allMax.First();
}
catch (SqlException ex)
{
if (ex.Number == 40615)
{
throw new Exception("Unable to connect to remote DB");
}
throw;
}
}
public double CountChars(string match, string words)
{
double result = 0;
string correctMatch = match.ToLower();
foreach (var word in words.Split('-'))
{
var correctWord = word.ToLower();
if (correctMatch.Contains(correctWord))
{
result = result + correctWord.Length - (double)(correctMatch.IndexOf(correctWord, StringComparison.Ordinal)) / 1000;
}
}
return result;
}