Fixed order of operations: search > filter & sort > slice

Also passing options.singleFilePath to search() for better perfs
This commit is contained in:
Simon Cambier
2022-12-05 12:59:53 +01:00
parent bb5f4285b0
commit a69e020738

View File

@@ -151,7 +151,7 @@ export class Omnisearch {
*/ */
public async search( public async search(
query: Query, query: Query,
options: { prefixLength: number } options: { prefixLength: number; singleFilePath?: string }
): Promise<SearchResult[]> { ): Promise<SearchResult[]> {
if (query.isEmpty()) { if (query.isEmpty()) {
this.previousResults = [] this.previousResults = []
@@ -172,6 +172,10 @@ export class Omnisearch {
}) })
if (!results.length) return this.previousResults if (!results.length) return this.previousResults
if (options.singleFilePath) {
return results.filter(r => r.id === options.singleFilePath)
}
// Hide or downrank files that are in Obsidian's excluded list // Hide or downrank files that are in Obsidian's excluded list
if (settings.hideExcluded) { if (settings.hideExcluded) {
// Filter the files out // Filter the files out
@@ -194,6 +198,20 @@ export class Omnisearch {
}) })
} }
// Extract tags from the query
const tags = query.segments
.filter(s => s.value.startsWith('#'))
.map(s => s.value)
// Put the results with tags on top
for (const tag of tags) {
for (const result of results) {
if ((result.tags ?? []).includes(tag)) {
result.score *= 100
}
}
}
results = results.slice(0, 50) results = results.slice(0, 50)
const documents = await Promise.all( const documents = await Promise.all(
@@ -266,14 +284,20 @@ export class Omnisearch {
*/ */
public async getSuggestions( public async getSuggestions(
query: Query, query: Query,
options?: Partial<{ singleFilePath: string | null }> options?: Partial<{ singleFilePath?: string }>
): Promise<ResultNote[]> { ): Promise<ResultNote[]> {
// Get the raw results // Get the raw results
let results: SearchResult[] let results: SearchResult[]
if (settings.simpleSearch) { if (settings.simpleSearch) {
results = await this.search(query, { prefixLength: 1 }) results = await this.search(query, {
prefixLength: 1,
singleFilePath: options?.singleFilePath,
})
} else { } else {
results = await this.search(query, { prefixLength: 3 }) results = await this.search(query, {
prefixLength: 3,
singleFilePath: options?.singleFilePath,
})
} }
// Extract tags from the query // Extract tags from the query
@@ -281,25 +305,6 @@ export class Omnisearch {
.filter(s => s.value.startsWith('#')) .filter(s => s.value.startsWith('#'))
.map(s => s.value) .map(s => s.value)
// Either keep the 50 first results,
// or the one corresponding to `singleFile`
if (options?.singleFilePath) {
const result = results.find(r => r.id === options.singleFilePath)
if (result) results = [result]
else results = []
} else {
results = results.slice(0, 50)
// Put the results with tags on top
for (const tag of tags) {
for (const result of results) {
if ((result.tags ?? []).includes(tag)) {
result.score *= 100
}
}
}
}
// TODO: this already called in search(), pass each document in its SearchResult instead? // TODO: this already called in search(), pass each document in its SearchResult instead?
const documents = await Promise.all( const documents = await Promise.all(
results.map(async result => await cacheManager.getDocument(result.id)) results.map(async result => await cacheManager.getDocument(result.id))