#151 - User-defined boosted fields

This commit is contained in:
Simon Cambier
2024-05-17 23:10:00 +02:00
parent c4211a0b09
commit 54bbe59db8
2 changed files with 93 additions and 26 deletions

View File

@@ -188,6 +188,7 @@ export class Omnisearch {
headings1: settings.weightH1,
headings2: settings.weightH2,
headings3: settings.weightH3,
tags: settings.weightUnmarkedTags,
unmarkedTags: settings.weightUnmarkedTags,
},
// The query is already tokenized, don't tokenize again
@@ -232,6 +233,11 @@ export class Omnisearch {
return results.filter(r => r.id === options.singleFilePath)
}
logDebug(
'searching with downranked folders',
settings.downrankedFoldersFilters
)
// Hide or downrank files that are in Obsidian's excluded list
if (settings.hideExcluded) {
// Filter the files out
@@ -254,14 +260,13 @@ export class Omnisearch {
})
}
logDebug(
'searching with downranked folders',
settings.downrankedFoldersFilters
)
// downrank files that are in folders listed in the downrankedFoldersFilters
if (settings.downrankedFoldersFilters.length > 0) {
results.forEach(result => {
const path = result.id
// Extract tags from the query
const tags = query.getTags()
for (const result of results) {
const path = result.id
if (settings.downrankedFoldersFilters.length > 0) {
// downrank files that are in folders listed in the downrankedFoldersFilters
let downrankingFolder = false
settings.downrankedFoldersFilters.forEach(filter => {
if (path.startsWith(filter)) {
@@ -285,21 +290,27 @@ export class Omnisearch {
break
}
}
})
}
}
// Extract tags from the query
const tags = query.getTags()
// Boost custom properties
const metadata = app.metadataCache.getCache(path)
if (metadata) {
for (const { name, weight } of settings.weightCustomProperties) {
const values = metadata?.frontmatter?.[name]
if (values && result.terms.some(t => values.includes(t))) {
logDebug(`Boosting field "${name}" x${weight} for ${path}`)
result.score *= weight
}
}
}
// Put the results with tags on top
for (const tag of tags) {
for (const result of results) {
// Put the results with tags on top
for (const tag of tags) {
if ((result.tags ?? []).includes(tag)) {
result.score *= 100
}
}
}
logDebug('Sorting and limiting results')
// Sort results and keep the 50 best

View File

@@ -1,3 +1,4 @@
// noinspection CssUnresolvedCustomProperty
import {
Notice,
Platform,
@@ -25,6 +26,7 @@ interface WeightingSettings {
}
export interface OmnisearchSettings extends WeightingSettings {
weightCustomProperties: { name: string; weight: number }[]
/** Enables caching to speed up indexing */
useCache: boolean
/** Respect the "excluded files" Obsidian setting by downranking results ignored files */
@@ -100,7 +102,7 @@ export class SettingsTab extends PluginSettingTab {
}
// Settings main title
containerEl.createEl('h2', { text: 'Omnisearch' })
containerEl.createEl('h1', { text: 'Omnisearch' })
// Sponsor link - Thank you!
const divSponsor = containerEl.createDiv()
@@ -131,7 +133,7 @@ export class SettingsTab extends PluginSettingTab {
// PDF Indexing
const indexPDFsDesc = new DocumentFragment()
indexPDFsDesc.createSpan({}, span => {
span.innerHTML = `Omnisearch will use Text Extractor to index the content of your PDFs`
span.innerHTML = `Omnisearch will use Text Extractor to index the content of your PDFs.`
})
new Setting(containerEl)
.setName(
@@ -150,7 +152,7 @@ export class SettingsTab extends PluginSettingTab {
// Images Indexing
const indexImagesDesc = new DocumentFragment()
indexImagesDesc.createSpan({}, span => {
span.innerHTML = `Omnisearch will use Text Extractor to OCR your images and index their content`
span.innerHTML = `Omnisearch will use Text Extractor to OCR your images and index their content.`
})
new Setting(containerEl)
.setName(`Images OCR indexing ${getTextExtractor() ? '' : '⚠️ Disabled'}`)
@@ -167,7 +169,7 @@ export class SettingsTab extends PluginSettingTab {
// Office Documents Indexing
const indexOfficesDesc = new DocumentFragment()
indexOfficesDesc.createSpan({}, span => {
span.innerHTML = `Omnisearch will use Text Extractor to index the content of your office documents (currently <pre style="display:inline">.docx</pre> and <pre style="display:inline">.xlsx</pre>)`
span.innerHTML = `Omnisearch will use Text Extractor to index the content of your office documents (currently <pre style="display:inline">.docx</pre> and <pre style="display:inline">.xlsx</pre>).`
})
new Setting(containerEl)
.setName(
@@ -189,7 +191,7 @@ export class SettingsTab extends PluginSettingTab {
span.innerHTML = `
Omnisearch can index file<strong>names</strong> of "unsupported" files, such as e.g. <pre style="display:inline">.mp4</pre>
or non-extracted PDFs & images.<br/>
"Obsidian setting" will respect the value of "Files & Links > Detect all file extensions"`
"Obsidian setting" will respect the value of "Files & Links > Detect all file extensions".`
})
new Setting(containerEl)
.setName('Index paths of unsupported files')
@@ -262,7 +264,7 @@ export class SettingsTab extends PluginSettingTab {
.setName('Respect Obsidian\'s "Excluded Files"')
.setDesc(
`By default, files that are in Obsidian\'s "Options > Files & Links > Excluded Files" list are downranked in results.
Enable this option to completely hide them`
Enable this option to completely hide them.`
)
.addToggle(toggle =>
toggle.setValue(settings.hideExcluded).onChange(async v => {
@@ -495,10 +497,63 @@ export class SettingsTab extends PluginSettingTab {
new Setting(containerEl)
.setName(
`Tags without the # (default: ${DEFAULT_SETTINGS.weightUnmarkedTags})`
`Tags (default: ${DEFAULT_SETTINGS.weightUnmarkedTags})`
)
.addSlider(cb => this.weightSlider(cb, 'weightUnmarkedTags'))
//#region Specific tags
new Setting(containerEl)
.setName('Header properties fields')
.setDesc('You can set custom weights for values of header properties (e.g. "keywords").')
for (let i = 0; i < settings.weightCustomProperties.length; i++) {
const item = settings.weightCustomProperties[i]
new Setting(containerEl)
.setName((i + 1).toString() + '.')
// TODO: add autocompletion from app.metadataCache.getAllPropertyInfos()
.addText(text => {
text
.setPlaceholder('Property name')
.setValue(item.name)
.onChange(async v => {
item.name = v
await saveSettings(this.plugin)
})
})
.addSlider(cb => {
cb.setLimits(1, 5, 0.1)
.setValue(item.weight)
.setDynamicTooltip()
.onChange(async v => {
item.weight = v
await saveSettings(this.plugin)
})
})
// Remove the tag
.addButton(btn => {
btn.setButtonText('Remove')
btn.onClick(async () => {
settings.weightCustomProperties.splice(i, 1)
await saveSettings(this.plugin)
this.display()
})
})
}
// Add a new custom tag
new Setting(containerEl)
.addButton(btn => {
btn.setButtonText('Add a new property')
btn.onClick(cb => {
settings.weightCustomProperties.push({ name: '', weight: 1 })
this.display()
})
})
//#endregion Specific tags
//#endregion Results Weighting
//#region HTTP Server
@@ -632,9 +687,9 @@ export class SettingsTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Clear cache data')
.setDesc(resetCacheDesc)
.addButton(cb => {
cb.setButtonText('Clear cache')
cb.onClick(async () => {
.addButton(btn => {
btn.setButtonText('Clear cache')
btn.onClick(async () => {
await database.clearCache()
})
})
@@ -683,6 +738,7 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
weightH2: 1.3,
weightH3: 1.1,
weightUnmarkedTags: 1.1,
weightCustomProperties: [] as { name: string; weight: number }[],
httpApiEnabled: false,
httpApiPort: '51361',