Exact page matches in search
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user