使用fuse.js实现嵌套对象数组模糊搜索的匹配异常问题
问题分析
你遇到的核心问题是:fuse.js 默认会返回整个匹配的父对象,而非仅返回父对象中匹配的子项。你的数据是按字母分组的结构,每个分组包含多个items子项,当搜索"banking"时,B分组里有一个子项匹配,所以整个B分组被完整返回,导致所有B开头的条目都被展示出来。
解决方案
根据你的需求,分两种场景处理:
场景1:只返回匹配的单个子项(而非整个分组)
如果希望搜索结果仅包含匹配的items子项(比如只返回{title: "Banking"}),需要先把原数据平铺成一维数组,再进行搜索:
// 将原分组数据平铺为所有子项的集合 const flattenedData = data.flatMap(group => group.items); // 初始化fuse时使用平铺后的数组 const fuse = new Fuse(flattenedData, { keys: ["title"], distance: 0.7, }); // 搜索结果直接提取匹配的子项 setItems(fuse.search(value).map(res => res.item));
场景2:保留分组结构,但仅保留分组内匹配的子项
如果需要保留原有的字母分组结构,但只在分组里展示匹配的子项,可以在搜索后对结果做二次过滤:
const searchResults = fuse.search(value).map(res => res.item); // 遍历每个分组,过滤出匹配搜索词的子项 const filteredGroups = searchResults.map(group => ({ ...group, items: group.items.filter(item => item.title.toLowerCase().includes(value.toLowerCase()) ) })); setItems(filteredGroups);
额外优化:提升匹配精度
如果希望匹配更严格,减少无关结果,可以调整threshold参数(默认值0.6,数值越小匹配越严格):
const fuse = new Fuse(formattedGlossar || [], { keys: ["items.title"], distance: 0.7, threshold: 0.3 // 缩小模糊匹配范围 });
补充说明
你参考的嵌套搜索示例,核心是让fuse.js能遍历嵌套的键路径,但它的返回逻辑依然是返回整个父对象,而非仅嵌套的匹配子项——这就是你得到整个B分组的原因。
内容的提问来源于stack exchange,提问作者Ayhan
相关产品推荐
相关产品推荐

