diff --git a/lib/shared/search-index.js b/lib/shared/search-index.js --- a/lib/shared/search-index.js +++ b/lib/shared/search-index.js @@ -2,6 +2,8 @@ import Tokenizer from 'tokenize-text'; +import RadixTree from './radix-tree.js'; + type Token = { index: number, match: { @@ -20,30 +22,14 @@ class SearchIndex { tokenize: (str: string) => Token[]; - fullTextIndex: { [token: string]: Set }; - partialTextIndex: { [token: string]: Set }; + radixTree: RadixTree = new RadixTree(); constructor(inputTokenize?: TokenizeFunc) { this.tokenize = inputTokenize ?? defaultTokenize; - this.fullTextIndex = {}; - this.partialTextIndex = {}; } addAllPrefixes(id: string, value: string): void { - if (this.fullTextIndex[value] === undefined) { - this.fullTextIndex[value] = new Set(); - } - this.fullTextIndex[value].add(id); - let partialString = ''; - for (let i = 0; i < value.length; i++) { - const char = value[i]; - partialString += char; - // TODO probably should do some stopwords here - if (this.partialTextIndex[partialString] === undefined) { - this.partialTextIndex[partialString] = new Set(); - } - this.partialTextIndex[partialString].add(id); - } + this.radixTree.add(value, id); } addEntry(id: string, rawText: string) { @@ -63,20 +49,21 @@ const lastKeyword = keywords[keywords.length - 1]; const lastKeywordValue = lastKeyword.value.toLowerCase(); const lastMatchSet = lastKeyword.match.input.match(/\S$/) - ? this.partialTextIndex[lastKeywordValue] - : this.fullTextIndex[lastKeywordValue]; - if (!lastMatchSet) { + ? this.radixTree.getAllMatchingPrefix(lastKeywordValue) + : this.radixTree.getAllMatchingExactly(lastKeywordValue); + if (lastMatchSet.length === 0) { return []; } const fullKeywords = keywords.slice(0, -1).map(k => k.value.toLowerCase()); - let possibleMatches: string[] = Array.from(lastMatchSet); + let possibleMatches = lastMatchSet; for (const keyword of fullKeywords) { - const fullMatches = this.fullTextIndex[keyword]; - if (!fullMatches) { + const fullMatches = this.radixTree.getAllMatchingExactly(keyword); + if (fullMatches.length === 0) { return []; } - possibleMatches = possibleMatches.filter(id => fullMatches.has(id)); + const fullMatchesSet = new Set(fullMatches); + possibleMatches = possibleMatches.filter(id => fullMatchesSet.has(id)); if (possibleMatches.length === 0) { return []; } diff --git a/lib/shared/sentence-prefix-search-index.js b/lib/shared/sentence-prefix-search-index.js --- a/lib/shared/sentence-prefix-search-index.js +++ b/lib/shared/sentence-prefix-search-index.js @@ -26,11 +26,7 @@ } getSearchResults(query: string): string[] { - const transformedQuery = query.toLowerCase(); - if (this.partialTextIndex[transformedQuery]) { - return Array.from(this.partialTextIndex[transformedQuery]); - } - return []; + return this.radixTree.getAllMatchingPrefix(query.toLowerCase()); } }