Exact page matches in search

This commit is contained in:
2026-07-20 09:08:35 +02:00
parent 5303645173
commit 34f750beff
3 changed files with 80 additions and 7 deletions
+20 -3
View File
@@ -18,6 +18,10 @@ import (
// section header still reports the true total so the user knows more exist.
const searchSectionCap = 10
// exactNameScore is the score scoreName assigns to a whole-name exact match.
// handleSearch peels these into the promoted "Exact Match" section.
const exactNameScore = 1000
type searchResult struct {
Name string
URL string
@@ -32,8 +36,11 @@ type searchPageData struct {
Title string
EditMode bool
Query string
Pages []searchResult
Files []searchResult
// Exact holds page(s) whose name equals the query exactly, promoted to
// their own section above the fuzzy matches.
Exact []searchResult
Pages []searchResult
Files []searchResult
// PageTotal/FileTotal are the true match totals; Pages/Files are capped at
// searchSectionCap for rendering.
PageTotal int
@@ -101,6 +108,15 @@ func (h *handler) handleSearch(w http.ResponseWriter, r *http.Request) {
pages, builtAt := searchWiki(query)
files := searchFiles(query)
// searchWiki sorts by score desc, so exact-name matches (score 1000) are
// at the front; peel them into their own section and drop them from the
// fuzzy page list so they aren't shown twice.
var exact []searchResult
for len(pages) > 0 && pages[0].Score == exactNameScore {
exact = append(exact, pages[0])
pages = pages[1:]
}
title := "Search"
if query != "" {
title = "Search: " + query
@@ -108,6 +124,7 @@ func (h *handler) handleSearch(w http.ResponseWriter, r *http.Request) {
data := searchPageData{
Title: title,
Query: query,
Exact: exact,
Pages: capResults(pages),
Files: capResults(files),
PageTotal: len(pages),
@@ -242,7 +259,7 @@ func fileURL(relPath string) string {
// large file volumes don't pay the edit-distance cost per query.
func scoreName(nameLower string, nameTokens []string, qLower string, qTokens []string, fuzzy bool) int {
if nameLower == qLower {
return 1000
return exactNameScore
}
score := 0
for _, qt := range qTokens {