Skip to content

Commit 7150693

Browse files
kartbencfriedt
authored andcommitted
doc: _extensions: kconfig: implement basic scoring of search results
This implements a few improvements to make Kconfig search results more relevant: - A match in a symbol's name is given more weight than a match in its prompt. - Field-length normalization is applied so that the shorter the field, the higher its relevance (e.g. searching for "sensor" will basically yield CONFIG_SENSOR as the top result as the query basically matches 100% of the symbol's name. Signed-off-by: Benjamin Cabé <[email protected]>
1 parent 028cf7f commit 7150693

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

doc/_extensions/zephyr/kconfig/static/kconfig.mjs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -349,28 +349,39 @@ function doSearch() {
349349
const regexes = input.value.trim().split(/\s+/).map(
350350
element => new RegExp(element.toLowerCase())
351351
);
352-
let count = 0;
353352

354-
const searchResults = db.filter(entry => {
355-
let matches = 0;
353+
const scoredResults = db.map(entry => {
354+
let nameMatches = 0;
355+
let promptMatches = 0;
356356
const name = entry.name.toLowerCase();
357357
const prompt = entry.prompt ? entry.prompt.toLowerCase() : "";
358358

359359
regexes.forEach(regex => {
360-
if (name.search(regex) >= 0 || prompt.search(regex) >= 0) {
361-
matches++;
362-
}
360+
if (name.search(regex) >= 0) nameMatches++;
361+
if (prompt.search(regex) >= 0) promptMatches++;
363362
});
364363

365-
if (matches === regexes.length) {
366-
count++;
367-
if (count > searchOffset && count <= (searchOffset + maxResults)) {
368-
return true;
369-
}
364+
const totalMatches = Math.max(nameMatches, promptMatches);
365+
if (totalMatches < regexes.length) {
366+
return null;
370367
}
371368

372-
return false;
373-
});
369+
const NAME_WEIGHT = 2.0;
370+
const PROMPT_WEIGHT = 1.0;
371+
/* Apply field-length normalization (the shorter the field, the higher its relevance) */
372+
const nameFieldNorm = 1.0 / Math.sqrt(name.length);
373+
const promptFieldNorm = prompt ? 1.0 / Math.sqrt(prompt.length) : 0;
374+
375+
const score = (nameMatches * NAME_WEIGHT * nameFieldNorm) +
376+
(promptMatches * PROMPT_WEIGHT * promptFieldNorm);
377+
378+
return { entry, score };
379+
}).filter(result => result !== null)
380+
.sort((a, b) => b.score - a.score);
381+
382+
const count = scoredResults.length;
383+
const searchResults = scoredResults.slice(searchOffset, searchOffset + maxResults)
384+
.map(result => result.entry);
374385

375386
/* show results count and search tools */
376387
summaryText.nodeValue = `${count} options match your search.`;

0 commit comments

Comments
 (0)