Fixed #48 - Highly favor tags in search results
This commit is contained in:
@@ -27,6 +27,7 @@ export type IndexedNote = {
|
||||
|
||||
content: string
|
||||
aliases: string
|
||||
tags: string[],
|
||||
headings1: string
|
||||
headings2: string
|
||||
headings3: string
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Notice, TAbstractFile, TFile } from 'obsidian'
|
||||
import MiniSearch, { type SearchResult } from 'minisearch'
|
||||
import MiniSearch, { type Options, type SearchResult } from 'minisearch'
|
||||
import {
|
||||
chsRegex,
|
||||
SPACE_OR_PUNCTUATION,
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
import {
|
||||
extractHeadingsFromCache,
|
||||
getAliasesFromMetadata,
|
||||
getTagsFromMetadata,
|
||||
removeDiacritics,
|
||||
stringsToRegex,
|
||||
stripMarkdownCharacters,
|
||||
@@ -51,7 +52,7 @@ const tokenize = (text: string): string[] => {
|
||||
* and adds all the notes to the index
|
||||
*/
|
||||
export async function initGlobalSearchIndex(): Promise<void> {
|
||||
const options = {
|
||||
const options: Options<IndexedNote> = {
|
||||
tokenize,
|
||||
processTerm: (term: string) =>
|
||||
(settings.ignoreDiacritics ? removeDiacritics(term) : term).toLowerCase(),
|
||||
@@ -64,6 +65,7 @@ export async function initGlobalSearchIndex(): Promise<void> {
|
||||
'headings2',
|
||||
'headings3',
|
||||
],
|
||||
storeFields: ['tags'],
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -234,6 +236,18 @@ export async function getSuggestions(
|
||||
}
|
||||
else {
|
||||
results = results.slice(0, 50)
|
||||
|
||||
// Put the results with tags on top
|
||||
const tags = query.segments
|
||||
.filter(s => s.value.startsWith('#'))
|
||||
.map(s => s.value)
|
||||
for (const tag of tags) {
|
||||
for (const result of results) {
|
||||
if (result.tags.includes(tag)) {
|
||||
result.score *= 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map the raw results to get usable suggestions
|
||||
@@ -243,6 +257,10 @@ export async function getSuggestions(
|
||||
throw new Error(`Note "${result.id}" not indexed`)
|
||||
}
|
||||
|
||||
// Remove '#' from tags, for highlighting
|
||||
query.segments.forEach(s => {
|
||||
s.value = s.value.replace(/^#/, '')
|
||||
})
|
||||
// Clean search matches that match quoted expressions,
|
||||
// and inject those expressions instead
|
||||
const foundWords = [
|
||||
@@ -251,6 +269,7 @@ export async function getSuggestions(
|
||||
),
|
||||
...query.segments.filter(s => s.exact).map(s => s.value),
|
||||
]
|
||||
|
||||
const matches = getMatches(note.content, stringsToRegex(foundWords))
|
||||
const resultNote: ResultNote = {
|
||||
score: result.score,
|
||||
@@ -307,6 +326,7 @@ export async function addToIndex(file: TAbstractFile): Promise<void> {
|
||||
path: file.path,
|
||||
mtime: file.stat.mtime,
|
||||
|
||||
tags: getTagsFromMetadata(metadata),
|
||||
aliases: getAliasesFromMetadata(metadata).join(''),
|
||||
headings1: metadata
|
||||
? extractHeadingsFromCache(metadata, 1).join(' ')
|
||||
|
||||
1
src/types.d.ts
vendored
1
src/types.d.ts
vendored
@@ -7,6 +7,7 @@ declare module 'obsidian' {
|
||||
|
||||
interface FrontMatterCache {
|
||||
aliases?: string[] | string
|
||||
tags?: string[] | string
|
||||
}
|
||||
|
||||
interface ViewState {
|
||||
|
||||
14
src/utils.ts
14
src/utils.ts
@@ -144,6 +144,20 @@ export function getAliasesFromMetadata(
|
||||
.filter(s => !!s)
|
||||
}
|
||||
|
||||
export function getTagsFromMetadata(metadata: CachedMetadata | null): string[] {
|
||||
const arrOrString = metadata?.frontmatter?.tags ?? []
|
||||
const fromFrontMatter = (
|
||||
Array.isArray(arrOrString) ? arrOrString : arrOrString.split(',')
|
||||
)
|
||||
.map(s => (s ? s.trim() : s))
|
||||
.filter(s => !!s)
|
||||
const fromBody = (metadata?.tags ?? []).map(t => t.tag)
|
||||
|
||||
return [...fromFrontMatter, ...fromBody].map(t =>
|
||||
t[0] !== '#' ? '#' + t : t,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/a/37511463
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user