mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-23 07:27:41 +01:00
Merge pull request #3106 from joenunezb/optimize/improve-search
perf(search): improve fuzzy character search performance by ~13x (4.5s → 350ms)
This commit is contained in:
commit
c3c16ea0d6
@ -1621,7 +1621,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
|
|||||||
subEntities = filterByTagState(entities, { subForEntity: entity });
|
subEntities = filterByTagState(entities, { subForEntity: entity });
|
||||||
if (doFilter) {
|
if (doFilter) {
|
||||||
// sub entities filter "hacked" because folder filter should not be applied there, so even in "only folders" mode characters show up
|
// sub entities filter "hacked" because folder filter should not be applied there, so even in "only folders" mode characters show up
|
||||||
subEntities = entitiesFilter.applyFilters(subEntities, { clearScoreCache: false, tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED } });
|
subEntities = entitiesFilter.applyFilters(subEntities, { clearScoreCache: false, tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false });
|
||||||
}
|
}
|
||||||
if (doSort) {
|
if (doSort) {
|
||||||
sortEntitiesList(subEntities);
|
sortEntitiesList(subEntities);
|
||||||
@ -1634,11 +1634,11 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
|
|||||||
// Second run filters, hiding whatever should be filtered later
|
// Second run filters, hiding whatever should be filtered later
|
||||||
if (doFilter) {
|
if (doFilter) {
|
||||||
const beforeFinalEntities = filterByTagState(entities, { globalDisplayFilters: true });
|
const beforeFinalEntities = filterByTagState(entities, { globalDisplayFilters: true });
|
||||||
entities = entitiesFilter.applyFilters(beforeFinalEntities);
|
entities = entitiesFilter.applyFilters(beforeFinalEntities, { clearFuzzySearchCaches: false });
|
||||||
|
|
||||||
// Magic for folder filter. If that one is enabled, and no folders are display anymore, we remove that filter to actually show the characters.
|
// Magic for folder filter. If that one is enabled, and no folders are display anymore, we remove that filter to actually show the characters.
|
||||||
if (isFilterState(entitiesFilter.getFilterData(FILTER_TYPES.FOLDER), FILTER_STATES.SELECTED) && entities.filter(x => x.type == 'tag').length == 0) {
|
if (isFilterState(entitiesFilter.getFilterData(FILTER_TYPES.FOLDER), FILTER_STATES.SELECTED) && entities.filter(x => x.type == 'tag').length == 0) {
|
||||||
entities = entitiesFilter.applyFilters(beforeFinalEntities, { tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED } });
|
entities = entitiesFilter.applyFilters(beforeFinalEntities, { tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1654,6 +1654,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
|
|||||||
if (doSort) {
|
if (doSort) {
|
||||||
sortEntitiesList(entities);
|
sortEntitiesList(entities);
|
||||||
}
|
}
|
||||||
|
entitiesFilter.clearFuzzySearchCaches();
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,19 @@ export function isFilterState(a, b) {
|
|||||||
return aKey === bKey;
|
return aKey === bKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fuzzy search categories
|
||||||
|
* @type {{ characters: string, worldInfo: string, personas: string, tags: string, groups: string }}
|
||||||
|
*/
|
||||||
|
export const fuzzySearchCategories = Object.freeze({
|
||||||
|
characters: 'characters',
|
||||||
|
worldInfo: 'worldInfo',
|
||||||
|
personas: 'personas',
|
||||||
|
tags: 'tags',
|
||||||
|
groups: 'groups',
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for filtering data.
|
* Helper class for filtering data.
|
||||||
* @example
|
* @example
|
||||||
@ -72,6 +85,12 @@ export class FilterHelper {
|
|||||||
*/
|
*/
|
||||||
scoreCache;
|
scoreCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache for fuzzy search results per category.
|
||||||
|
* @type {Object.<string, { resultMap: Map<string, any> }>}
|
||||||
|
*/
|
||||||
|
fuzzySearchCaches;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new FilterHelper
|
* Creates a new FilterHelper
|
||||||
* @param {Function} onDataChanged Callback to trigger when the filter data changes
|
* @param {Function} onDataChanged Callback to trigger when the filter data changes
|
||||||
@ -79,6 +98,13 @@ export class FilterHelper {
|
|||||||
constructor(onDataChanged) {
|
constructor(onDataChanged) {
|
||||||
this.onDataChanged = onDataChanged;
|
this.onDataChanged = onDataChanged;
|
||||||
this.scoreCache = new Map();
|
this.scoreCache = new Map();
|
||||||
|
this.fuzzySearchCaches = {
|
||||||
|
[fuzzySearchCategories.characters]: { resultMap: new Map() },
|
||||||
|
[fuzzySearchCategories.worldInfo]: { resultMap: new Map() },
|
||||||
|
[fuzzySearchCategories.personas]: { resultMap: new Map() },
|
||||||
|
[fuzzySearchCategories.tags]: { resultMap: new Map() },
|
||||||
|
[fuzzySearchCategories.groups]: { resultMap: new Map() },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +177,7 @@ export class FilterHelper {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fuzzySearchResults = fuzzySearchWorldInfo(data, term);
|
const fuzzySearchResults = fuzzySearchWorldInfo(data, term, this.fuzzySearchCaches);
|
||||||
this.cacheScores(FILTER_TYPES.WORLD_INFO_SEARCH, new Map(fuzzySearchResults.map(i => [i.item?.uid, i.score])));
|
this.cacheScores(FILTER_TYPES.WORLD_INFO_SEARCH, new Map(fuzzySearchResults.map(i => [i.item?.uid, i.score])));
|
||||||
|
|
||||||
const filteredData = data.filter(entity => fuzzySearchResults.find(x => x.item === entity));
|
const filteredData = data.filter(entity => fuzzySearchResults.find(x => x.item === entity));
|
||||||
@ -170,7 +196,7 @@ export class FilterHelper {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fuzzySearchResults = fuzzySearchPersonas(data, term);
|
const fuzzySearchResults = fuzzySearchPersonas(data, term, this.fuzzySearchCaches);
|
||||||
this.cacheScores(FILTER_TYPES.PERSONA_SEARCH, new Map(fuzzySearchResults.map(i => [i.item.key, i.score])));
|
this.cacheScores(FILTER_TYPES.PERSONA_SEARCH, new Map(fuzzySearchResults.map(i => [i.item.key, i.score])));
|
||||||
|
|
||||||
const filteredData = data.filter(name => fuzzySearchResults.find(x => x.item.key === name));
|
const filteredData = data.filter(name => fuzzySearchResults.find(x => x.item.key === name));
|
||||||
@ -289,9 +315,9 @@ export class FilterHelper {
|
|||||||
|
|
||||||
// Save fuzzy search results and scores if enabled
|
// Save fuzzy search results and scores if enabled
|
||||||
if (power_user.fuzzy_search) {
|
if (power_user.fuzzy_search) {
|
||||||
const fuzzySearchCharactersResults = fuzzySearchCharacters(searchValue);
|
const fuzzySearchCharactersResults = fuzzySearchCharacters(searchValue, this.fuzzySearchCaches);
|
||||||
const fuzzySearchGroupsResults = fuzzySearchGroups(searchValue);
|
const fuzzySearchGroupsResults = fuzzySearchGroups(searchValue, this.fuzzySearchCaches);
|
||||||
const fuzzySearchTagsResult = fuzzySearchTags(searchValue);
|
const fuzzySearchTagsResult = fuzzySearchTags(searchValue, this.fuzzySearchCaches);
|
||||||
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchCharactersResults.map(i => [`character.${i.refIndex}`, i.score])));
|
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchCharactersResults.map(i => [`character.${i.refIndex}`, i.score])));
|
||||||
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchGroupsResults.map(i => [`group.${i.item.id}`, i.score])));
|
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchGroupsResults.map(i => [`group.${i.item.id}`, i.score])));
|
||||||
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchTagsResult.map(i => [`tag.${i.item.id}`, i.score])));
|
this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchTagsResult.map(i => [`tag.${i.item.id}`, i.score])));
|
||||||
@ -343,11 +369,14 @@ export class FilterHelper {
|
|||||||
* @param {object} options - Optional call parameters
|
* @param {object} options - Optional call parameters
|
||||||
* @param {boolean} [options.clearScoreCache=true] - Whether the score cache should be cleared.
|
* @param {boolean} [options.clearScoreCache=true] - Whether the score cache should be cleared.
|
||||||
* @param {Object.<FilterType, any>} [options.tempOverrides={}] - Temporarily override specific filters for this filter application
|
* @param {Object.<FilterType, any>} [options.tempOverrides={}] - Temporarily override specific filters for this filter application
|
||||||
|
* @param {boolean} [options.clearFuzzySearchCaches=true] - Whether the fuzzy search caches should be cleared.
|
||||||
* @returns {any[]} The filtered data.
|
* @returns {any[]} The filtered data.
|
||||||
*/
|
*/
|
||||||
applyFilters(data, { clearScoreCache = true, tempOverrides = {} } = {}) {
|
applyFilters(data, { clearScoreCache = true, tempOverrides = {}, clearFuzzySearchCaches = true } = {}) {
|
||||||
if (clearScoreCache) this.clearScoreCache();
|
if (clearScoreCache) this.clearScoreCache();
|
||||||
|
|
||||||
|
if (clearFuzzySearchCaches) this.clearFuzzySearchCaches();
|
||||||
|
|
||||||
// Save original filter states
|
// Save original filter states
|
||||||
const originalStates = {};
|
const originalStates = {};
|
||||||
for (const key in tempOverrides) {
|
for (const key in tempOverrides) {
|
||||||
@ -411,4 +440,14 @@ export class FilterHelper {
|
|||||||
this.scoreCache = new Map();
|
this.scoreCache = new Map();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears fuzzy search caches
|
||||||
|
*/
|
||||||
|
clearFuzzySearchCaches() {
|
||||||
|
for (const cache of Object.values(this.fuzzySearchCaches)) {
|
||||||
|
cache.resultMap.clear();
|
||||||
|
}
|
||||||
|
console.log('All fuzzy search caches cleared');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandE
|
|||||||
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { POPUP_TYPE, callGenericPopup } from './popup.js';
|
import { POPUP_TYPE, callGenericPopup } from './popup.js';
|
||||||
import { loadSystemPrompts } from './sysprompt.js';
|
import { loadSystemPrompts } from './sysprompt.js';
|
||||||
|
import { fuzzySearchCategories } from './filters.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
loadPowerUserSettings,
|
loadPowerUserSettings,
|
||||||
@ -1829,27 +1830,28 @@ async function loadContextSettings() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuzzy search characters by a search term
|
* Common function to perform fuzzy search with optional caching
|
||||||
|
* @param {string} type - Type of search from fuzzySearchCategories
|
||||||
|
* @param {any[]} data - Data array to search in
|
||||||
|
* @param {Array<{name: string, weight: number, getFn?: Function}>} keys - Fuse.js keys configuration
|
||||||
* @param {string} searchValue - The search term
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
*/
|
*/
|
||||||
export function fuzzySearchCharacters(searchValue) {
|
function performFuzzySearch(type, data, keys, searchValue, fuzzySearchCaches = null) {
|
||||||
|
// Check cache if provided
|
||||||
|
if (fuzzySearchCaches) {
|
||||||
|
const cache = fuzzySearchCaches[type];
|
||||||
|
if (cache?.resultMap.has(searchValue)) {
|
||||||
|
return cache.resultMap.get(searchValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const fuse = new Fuse(characters, {
|
const fuse = new Fuse(data, {
|
||||||
keys: [
|
keys: keys,
|
||||||
{ name: 'data.name', weight: 20 },
|
|
||||||
{ name: '#tags', weight: 10, getFn: (character) => getTagsList(character.avatar).map(x => x.name).join('||') },
|
|
||||||
{ name: 'data.description', weight: 3 },
|
|
||||||
{ name: 'data.mes_example', weight: 3 },
|
|
||||||
{ name: 'data.scenario', weight: 2 },
|
|
||||||
{ name: 'data.personality', weight: 2 },
|
|
||||||
{ name: 'data.first_mes', weight: 2 },
|
|
||||||
{ name: 'data.creator_notes', weight: 2 },
|
|
||||||
{ name: 'data.creator', weight: 1 },
|
|
||||||
{ name: 'data.tags', weight: 1 },
|
|
||||||
{ name: 'data.alternate_greetings', weight: 1 },
|
|
||||||
],
|
|
||||||
includeScore: true,
|
includeScore: true,
|
||||||
ignoreLocation: true,
|
ignoreLocation: true,
|
||||||
useExtendedSearch: true,
|
useExtendedSearch: true,
|
||||||
@ -1857,109 +1859,110 @@ export function fuzzySearchCharacters(searchValue) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const results = fuse.search(searchValue);
|
const results = fuse.search(searchValue);
|
||||||
console.debug('Characters fuzzy search results for ' + searchValue, results);
|
|
||||||
|
// Store in cache if provided
|
||||||
|
if (fuzzySearchCaches) {
|
||||||
|
fuzzySearchCaches[type].resultMap.set(searchValue, results);
|
||||||
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fuzzy search characters by a search term
|
||||||
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
|
*/
|
||||||
|
export function fuzzySearchCharacters(searchValue, fuzzySearchCaches = null) {
|
||||||
|
const keys = [
|
||||||
|
{ name: 'data.name', weight: 20 },
|
||||||
|
{ name: '#tags', weight: 10, getFn: (character) => getTagsList(character.avatar).map(x => x.name).join('||') },
|
||||||
|
{ name: 'data.description', weight: 3 },
|
||||||
|
{ name: 'data.mes_example', weight: 3 },
|
||||||
|
{ name: 'data.scenario', weight: 2 },
|
||||||
|
{ name: 'data.personality', weight: 2 },
|
||||||
|
{ name: 'data.first_mes', weight: 2 },
|
||||||
|
{ name: 'data.creator_notes', weight: 2 },
|
||||||
|
{ name: 'data.creator', weight: 1 },
|
||||||
|
{ name: 'data.tags', weight: 1 },
|
||||||
|
{ name: 'data.alternate_greetings', weight: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
return performFuzzySearch(fuzzySearchCategories.characters, characters, keys, searchValue, fuzzySearchCaches);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuzzy search world info entries by a search term
|
* Fuzzy search world info entries by a search term
|
||||||
* @param {*[]} data - WI items data array
|
* @param {*[]} data - WI items data array
|
||||||
* @param {string} searchValue - The search term
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
*/
|
*/
|
||||||
export function fuzzySearchWorldInfo(data, searchValue) {
|
export function fuzzySearchWorldInfo(data, searchValue, fuzzySearchCaches = null) {
|
||||||
// @ts-ignore
|
const keys = [
|
||||||
const fuse = new Fuse(data, {
|
{ name: 'key', weight: 20 },
|
||||||
keys: [
|
{ name: 'group', weight: 15 },
|
||||||
{ name: 'key', weight: 20 },
|
{ name: 'comment', weight: 10 },
|
||||||
{ name: 'group', weight: 15 },
|
{ name: 'keysecondary', weight: 10 },
|
||||||
{ name: 'comment', weight: 10 },
|
{ name: 'content', weight: 3 },
|
||||||
{ name: 'keysecondary', weight: 10 },
|
{ name: 'uid', weight: 1 },
|
||||||
{ name: 'content', weight: 3 },
|
{ name: 'automationId', weight: 1 },
|
||||||
{ name: 'uid', weight: 1 },
|
];
|
||||||
{ name: 'automationId', weight: 1 },
|
|
||||||
],
|
|
||||||
includeScore: true,
|
|
||||||
ignoreLocation: true,
|
|
||||||
useExtendedSearch: true,
|
|
||||||
threshold: 0.2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = fuse.search(searchValue);
|
return performFuzzySearch(fuzzySearchCategories.worldInfo, data, keys, searchValue, fuzzySearchCaches);
|
||||||
console.debug('World Info fuzzy search results for ' + searchValue, results);
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuzzy search persona entries by a search term
|
* Fuzzy search persona entries by a search term
|
||||||
* @param {*[]} data - persona data array
|
* @param {*[]} data - persona data array
|
||||||
* @param {string} searchValue - The search term
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
*/
|
*/
|
||||||
export function fuzzySearchPersonas(data, searchValue) {
|
export function fuzzySearchPersonas(data, searchValue, fuzzySearchCaches = null) {
|
||||||
data = data.map(x => ({ key: x, name: power_user.personas[x] ?? '', description: power_user.persona_descriptions[x]?.description ?? '' }));
|
const mappedData = data.map(x => ({
|
||||||
// @ts-ignore
|
key: x,
|
||||||
const fuse = new Fuse(data, {
|
name: power_user.personas[x] ?? '',
|
||||||
keys: [
|
description: power_user.persona_descriptions[x]?.description ?? ''
|
||||||
{ name: 'name', weight: 20 },
|
}));
|
||||||
{ name: 'description', weight: 3 },
|
|
||||||
],
|
|
||||||
includeScore: true,
|
|
||||||
ignoreLocation: true,
|
|
||||||
useExtendedSearch: true,
|
|
||||||
threshold: 0.2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = fuse.search(searchValue);
|
const keys = [
|
||||||
console.debug('Personas fuzzy search results for ' + searchValue, results);
|
{ name: 'name', weight: 20 },
|
||||||
return results;
|
{ name: 'description', weight: 3 },
|
||||||
|
];
|
||||||
|
|
||||||
|
return performFuzzySearch(fuzzySearchCategories.personas, mappedData, keys, searchValue, fuzzySearchCaches);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuzzy search tags by a search term
|
* Fuzzy search tags by a search term
|
||||||
* @param {string} searchValue - The search term
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
*/
|
*/
|
||||||
export function fuzzySearchTags(searchValue) {
|
export function fuzzySearchTags(searchValue, fuzzySearchCaches = null) {
|
||||||
// @ts-ignore
|
const keys = [
|
||||||
const fuse = new Fuse(tags, {
|
{ name: 'name', weight: 1 },
|
||||||
keys: [
|
];
|
||||||
{ name: 'name', weight: 1 },
|
|
||||||
],
|
|
||||||
includeScore: true,
|
|
||||||
ignoreLocation: true,
|
|
||||||
useExtendedSearch: true,
|
|
||||||
threshold: 0.2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = fuse.search(searchValue);
|
return performFuzzySearch(fuzzySearchCategories.tags, tags, keys, searchValue, fuzzySearchCaches);
|
||||||
console.debug('Tags fuzzy search results for ' + searchValue, results);
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuzzy search groups by a search term
|
* Fuzzy search groups by a search term
|
||||||
* @param {string} searchValue - The search term
|
* @param {string} searchValue - The search term
|
||||||
|
* @param {Object.<string, { resultMap: Map<string, any> }>} [fuzzySearchCaches=null] - Optional fuzzy search caches
|
||||||
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
* @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
|
||||||
*/
|
*/
|
||||||
export function fuzzySearchGroups(searchValue) {
|
export function fuzzySearchGroups(searchValue, fuzzySearchCaches = null) {
|
||||||
// @ts-ignore
|
const keys = [
|
||||||
const fuse = new Fuse(groups, {
|
{ name: 'name', weight: 20 },
|
||||||
keys: [
|
{ name: 'members', weight: 15 },
|
||||||
{ name: 'name', weight: 20 },
|
{ name: '#tags', weight: 10, getFn: (group) => getTagsList(group.id).map(x => x.name).join('||') },
|
||||||
{ name: 'members', weight: 15 },
|
{ name: 'id', weight: 1 },
|
||||||
{ name: '#tags', weight: 10, getFn: (group) => getTagsList(group.id).map(x => x.name).join('||') },
|
];
|
||||||
{ name: 'id', weight: 1 },
|
|
||||||
],
|
|
||||||
includeScore: true,
|
|
||||||
ignoreLocation: true,
|
|
||||||
useExtendedSearch: true,
|
|
||||||
threshold: 0.2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = fuse.search(searchValue);
|
return performFuzzySearch(fuzzySearchCategories.groups, groups, keys, searchValue, fuzzySearchCaches);
|
||||||
console.debug('Groups fuzzy search results for ' + searchValue, results);
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user