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();
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 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 matchedTokens = 0;
let exactMatches = 0;
let partialMatches = 0;
let significantMatches = 0;
qTokens.forEach(qToken => {
const isStopword = stopwords.has(qToken);
let bestMatch = 0;
let hasExactMatch = false;
tTokens.forEach(tToken => {
let matchScore = 0;
if (tToken === qToken) {
matchScore = isStopword ? 20 : 100;
matchScore = isStopword ? 25 : 120;
hasExactMatch = true;
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++;
} 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++;
} else if (qToken.length >= 3 && tToken.length >= 3) {
}
else if (qToken.length >= 4 && tToken.length >= 4) {
const dist = levenshteinDistance(qToken, tToken);
const maxLen = Math.max(qToken.length, tToken.length);
const similarity = 1 - (dist / maxLen);
if (similarity > 0.7) {
matchScore = Math.floor(similarity * 40);
if (similarity > 0.8) {
matchScore = Math.floor(similarity * 60);
if (!isStopword) significantMatches++;
}
}
@ -64,37 +74,39 @@ async function searchResults(query) {
if (bestMatch > 0) {
score += bestMatch;
matchedTokens++;
if (hasExactMatch) exactMatches++;
else partialMatches++;
}
});
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) {
return 0;
return 0;
}
if (matchedTokens >= qTokens.length) {
score += 100;
if (exactMatches + partialMatches >= qTokens.length) {
score += 80;
}
if (t.startsWith(q)) {
score += 150;
}
score += exactMatches * 20;
const extraWords = tTokens.length - qTokens.length;
if (extraWords > 3) {
score -= (extraWords - 3) * 20;
if (extraWords > 2) {
score -= (extraWords - 2) * 25;
}
let orderBonus = 0;
for (let i = 0; i < qTokens.length - 1; i++) {
const bigram = qTokens[i] + ' ' + qTokens[i + 1];
const bigramNoDash = qTokens[i] + qTokens[i + 1];
if (!t.includes(bigram) && !t.includes(bigramNoDash)) {
score -= 15;
const currentTokenIndex = tTokens.findIndex(t => t.includes(qTokens[i]));
const nextTokenIndex = tTokens.findIndex(t => t.includes(qTokens[i + 1]));
if (currentTokenIndex !== -1 && nextTokenIndex !== -1 && currentTokenIndex < nextTokenIndex) {
orderBonus += 15;
}
}
score += orderBonus;
return Math.max(0, score);
};
@ -248,9 +260,9 @@ async function searchResults(query) {
}));
const filteredResults = scoredResults
.filter(r => r.score > 0)
.sort((a, b) => b.score - a.score)
.map(({ score, ...rest }) => rest);
.filter(r => r.score > 50) // Increased threshold to filter out weak matches
.sort((a, b) => b.score - a.score) // Sort by pre-calculated scores
.map(({ score, ...rest }) => rest);
return JSON.stringify(filteredResults.length > 0 ? filteredResults : [{
href: "",