mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
refactor: use token-based fuzzy matching for flexible search
Some checks failed
CI / build-and-test (push) Has been cancelled
Some checks failed
CI / build-and-test (push) Has been cancelled
This commit is contained in:
@@ -1785,45 +1785,39 @@ public class JellyfinController : ControllerBase
|
|||||||
var artist = artistField(item) ?? "";
|
var artist = artistField(item) ?? "";
|
||||||
var album = albumField(item) ?? "";
|
var album = albumField(item) ?? "";
|
||||||
|
|
||||||
var scores = new List<int>();
|
// Token-based fuzzy matching: split query and fields into words
|
||||||
|
var queryTokens = query.ToLower()
|
||||||
|
.Split(new[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
// Individual field scores
|
var fieldText = $"{title} {artist} {album}".ToLower();
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, title));
|
var fieldTokens = fieldText
|
||||||
if (!string.IsNullOrEmpty(artist))
|
.Split(new[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, artist));
|
.ToList();
|
||||||
if (!string.IsNullOrEmpty(album))
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, album));
|
|
||||||
|
|
||||||
// Two-field combinations
|
if (queryTokens.Count == 0) return (item, 0);
|
||||||
if (!string.IsNullOrEmpty(artist))
|
|
||||||
|
// Count how many query tokens match field tokens (with fuzzy tolerance)
|
||||||
|
var matchedTokens = 0;
|
||||||
|
foreach (var queryToken in queryTokens)
|
||||||
{
|
{
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{title} {artist}"));
|
// Check if any field token matches this query token
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{artist} {title}"));
|
var hasMatch = fieldTokens.Any(fieldToken =>
|
||||||
}
|
{
|
||||||
if (!string.IsNullOrEmpty(album))
|
// Exact match or substring match
|
||||||
{
|
if (fieldToken.Contains(queryToken) || queryToken.Contains(fieldToken))
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{title} {album}"));
|
return true;
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{album} {title}"));
|
|
||||||
}
|
// Fuzzy match with Levenshtein distance
|
||||||
if (!string.IsNullOrEmpty(artist) && !string.IsNullOrEmpty(album))
|
var similarity = FuzzyMatcher.CalculateSimilarity(queryToken, fieldToken);
|
||||||
{
|
return similarity >= 70; // 70% similarity threshold for individual words
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{artist} {album}"));
|
});
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{album} {artist}"));
|
|
||||||
|
if (hasMatch) matchedTokens++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Three-field combinations (all permutations)
|
// Score = percentage of query tokens that matched
|
||||||
if (!string.IsNullOrEmpty(artist) && !string.IsNullOrEmpty(album))
|
var baseScore = (matchedTokens * 100) / queryTokens.Count;
|
||||||
{
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{title} {artist} {album}"));
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{title} {album} {artist}"));
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{artist} {title} {album}"));
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{artist} {album} {title}"));
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{album} {title} {artist}"));
|
|
||||||
scores.Add(FuzzyMatcher.CalculateSimilarity(query, $"{album} {artist} {title}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the best score from all attempts
|
|
||||||
var baseScore = scores.Max();
|
|
||||||
|
|
||||||
// Give external results a small boost (+5 points) to prioritize the larger catalog
|
// Give external results a small boost (+5 points) to prioritize the larger catalog
|
||||||
var finalScore = isExternal ? Math.Min(100, baseScore + 5) : baseScore;
|
var finalScore = isExternal ? Math.Min(100, baseScore + 5) : baseScore;
|
||||||
|
|||||||
Reference in New Issue
Block a user