Update ashi/ashi.js

This commit is contained in:
aka paul 2025-10-12 22:06:54 +00:00
parent 8a6647da9e
commit 487f91ad11

View file

@ -21,40 +21,50 @@ async function searchResults(query) {
const t = title.toLowerCase().trim(); const t = title.toLowerCase().trim();
if (t === q) return 1000; if (t === q) return 1000;
if (t.includes(q)) return 900;
if (t.startsWith(q + ' ') || t.startsWith(q + ':') || t.startsWith(q + '-')) return 950;
const wordBoundaryRegex = new RegExp(`\\b${q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`);
if (wordBoundaryRegex.test(t)) return 900;
const qTokens = q.split(/\s+/).filter(token => token.length > 0); const qTokens = q.split(/\s+/).filter(token => token.length > 0);
const tTokens = t.split(/[\s\-]+/).filter(token => token.length > 0); const tTokens = t.split(/[\s\-:]+/).filter(token => token.length > 0);
const stopwords = new Set(['the', 'a', 'an', 'and', 'or', 'of', 'in', 'on', 'at', 'to', 'for']); const stopwords = new Set(['the', 'a', 'an', 'and', 'or', 'of', 'in', 'on', 'at', 'to', 'for', 'with']);
let score = 0; let score = 0;
let matchedTokens = 0; let exactMatches = 0;
let partialMatches = 0;
let significantMatches = 0; let significantMatches = 0;
qTokens.forEach(qToken => { qTokens.forEach(qToken => {
const isStopword = stopwords.has(qToken); const isStopword = stopwords.has(qToken);
let bestMatch = 0; let bestMatch = 0;
let hasExactMatch = false;
tTokens.forEach(tToken => { tTokens.forEach(tToken => {
let matchScore = 0; let matchScore = 0;
if (tToken === qToken) { if (tToken === qToken) {
matchScore = isStopword ? 20 : 100; matchScore = isStopword ? 25 : 120;
hasExactMatch = true;
if (!isStopword) significantMatches++; if (!isStopword) significantMatches++;
} else if (tToken.includes(qToken) && qToken.length >= 3) { }
matchScore = isStopword ? 10 : 60; else if (qToken.includes(tToken) && tToken.length >= 3 && qToken.length <= tToken.length + 2) {
matchScore = isStopword ? 8 : 40;
if (!isStopword) significantMatches++; if (!isStopword) significantMatches++;
} else if (qToken.includes(tToken) && tToken.length >= 3) { }
matchScore = isStopword ? 10 : 50; else if (tToken.startsWith(qToken) && qToken.length >= 3) {
matchScore = isStopword ? 12 : 70;
if (!isStopword) significantMatches++; if (!isStopword) significantMatches++;
} else if (qToken.length >= 3 && tToken.length >= 3) { }
else if (qToken.length >= 4 && tToken.length >= 4) {
const dist = levenshteinDistance(qToken, tToken); const dist = levenshteinDistance(qToken, tToken);
const maxLen = Math.max(qToken.length, tToken.length); const maxLen = Math.max(qToken.length, tToken.length);
const similarity = 1 - (dist / maxLen); const similarity = 1 - (dist / maxLen);
if (similarity > 0.7) { if (similarity > 0.8) {
matchScore = Math.floor(similarity * 40); matchScore = Math.floor(similarity * 60);
if (!isStopword) significantMatches++; if (!isStopword) significantMatches++;
} }
} }
@ -64,37 +74,39 @@ async function searchResults(query) {
if (bestMatch > 0) { if (bestMatch > 0) {
score += bestMatch; score += bestMatch;
matchedTokens++; if (hasExactMatch) exactMatches++;
else partialMatches++;
} }
}); });
const significantTokens = qTokens.filter(t => !stopwords.has(t)).length; const significantTokens = qTokens.filter(t => !stopwords.has(t)).length;
const requiredMatches = Math.ceil(significantTokens * 0.7); const requiredMatches = Math.max(1, Math.ceil(significantTokens * 0.8));
if (significantMatches < requiredMatches) { if (significantMatches < requiredMatches) {
return 0; return 0;
} }
if (matchedTokens >= qTokens.length) { if (exactMatches + partialMatches >= qTokens.length) {
score += 100; score += 80;
} }
if (t.startsWith(q)) { score += exactMatches * 20;
score += 150;
}
const extraWords = tTokens.length - qTokens.length; const extraWords = tTokens.length - qTokens.length;
if (extraWords > 3) { if (extraWords > 2) {
score -= (extraWords - 3) * 20; score -= (extraWords - 2) * 25;
} }
let orderBonus = 0;
for (let i = 0; i < qTokens.length - 1; i++) { for (let i = 0; i < qTokens.length - 1; i++) {
const bigram = qTokens[i] + ' ' + qTokens[i + 1]; const currentTokenIndex = tTokens.findIndex(t => t.includes(qTokens[i]));
const bigramNoDash = qTokens[i] + qTokens[i + 1]; const nextTokenIndex = tTokens.findIndex(t => t.includes(qTokens[i + 1]));
if (!t.includes(bigram) && !t.includes(bigramNoDash)) {
score -= 15; if (currentTokenIndex !== -1 && nextTokenIndex !== -1 && currentTokenIndex < nextTokenIndex) {
orderBonus += 15;
} }
} }
score += orderBonus;
return Math.max(0, score); return Math.max(0, score);
}; };
@ -248,8 +260,8 @@ async function searchResults(query) {
})); }));
const filteredResults = scoredResults const filteredResults = scoredResults
.filter(r => r.score > 0) .filter(r => r.score > 50) // Increased threshold to filter out weak matches
.sort((a, b) => b.score - a.score) .sort((a, b) => b.score - a.score) // Sort by pre-calculated scores
.map(({ score, ...rest }) => rest); .map(({ score, ...rest }) => rest);
return JSON.stringify(filteredResults.length > 0 ? filteredResults : [{ return JSON.stringify(filteredResults.length > 0 ? filteredResults : [{