搜索文件夹
寻找它的意义.
你开始打字,你得到你需要去的地方。 一个错误的字母在一个
名称 — SoundCloud 失败, 艺人因为键入而无法找到
kayne - 仍然发现它。 0依赖; 反应可选.
2026-10-12年对舰队进行的一项调查发现约有25个搜索箱,其中1个带有
任何打字耐受性(substrata自己的引擎). 其余的则
text.toLowerCase().includes(q) 或 SQL ILIKE '%q%': 没有打字,没有
排行榜,几个不逃 %每个新网站都会写26号.
它住在哪里,一个网站如何采用它
由 bitbaum/ fleet 创建的这个 repo package-repos 工作流程来源
bitbaum/orangecat packages/searchkit (它的历史在0.2.2是在那里).
一个站点安装 npm 的释放, 这取决于自行前进 :
// package.json
"@bitbaum/searchkit": "^0.2.2"
它的船编译 JavaScript in dist/,在源头旁边 的方式
@bitbaum/whenkit 下个,J,Vitest,和
节点自己的测试跑取器( 拒绝内置类型脚本) node_modules全部)
继续装 测试在 test/ 并使用平原节点运行(npm test(三);
其中一个失败了 dist/ 不是建造 src/ (单位:千美元)npm run build) (中文(简体) ).
舰队的每一个搜索箱都应该经过它. 第一个收养人,
OrangeCat,在三个地方运行: QQ调色板自己的列表(页,您
东西, /api/search (vocabulary 更正交给Postgres,然后
排名)和 /discover。 。 。 .
飞来飞去
import { createSearch } from '@bitbaum/searchkit';
const people = createSearch(rows, {
fields: [
{ name: 'name', get: p => p.name }, // most important first
{ name: 'handle', get: p => p.username },
{ name: 'bio', get: p => p.bio },
],
rank: p => Math.log1p(p.followers), // last tie-break only
});
people.search('kayne wset'); // → Kanye West, with ranges to mark
匹配——什么是同一个词
| 类型 | 发现 | 怎么样 |
|---|---|---|
cqto | 凯托 | 1个错误字母(预算:4个字母下的0个打字,4个字母中的1个,8个字母中的2个) |
kayne | 坎叶 | 互换是 ONE 类型( 最佳字符串对齐) |
koki | 罗基 | 错误的第一个字母仍然匹配 —— 排序为两个打字符 |
lo | 罗基 | 输入时开始一个单词 |
bitcon | 比特币 | 一个字开头的打字 |
zurich, (中文(简体) ), mueller | 苏里希,穆勒 | 重音折叠; umlauts 也拼出索引 |
orangecat, (中文(简体) ), orange cat | 橙猫,橙猫 | 骆驼Case和分隔符拆分;相邻的单词也加入索引(当文本将它们分开时排序为打字符),所以 catto 还是先找到Cato |
cato xylophone | 凯托 | 匹配无一物的词被搁置,而不是致命的 |
jon smith | 约翰·史密斯 | 当没有任何项目有每个字时,任何项目所保存的字数最多——无论是哪个字 |
预算是Algolia和Typesense使用的预算。 Meilisearch的 (一个打字来自 5个字母, 第一个字母的打字费用为 2 个) 找不到错误的4个字母名称 还有一个5到8个字母的第一个字母滑了下来.
排名——打平分而不是加权总和
每项规则只决定结果与结果之间
字形 字相匹配 字段 准确性(整个字段打出,然后是全字段)
单词,然后前缀) 相近 实地位置 – 您 rank →
较短的战地。 和数需要调和和漂移;长篇描述超过分数 a
简短的题目。 这是阿尔戈利亚公布的订单,根据名字进行调整.
在数据库中运行的搜索
原谅部分不需要在数据库中存在 。 留着
收藏的词createVocabulary),将输入的字扩展为
它可能意味着,并发送这些一起:
import { corrections, createVocabulary, didYouMean } from '@bitbaum/searchkit';
const vocab = createVocabulary(wordsWithCounts); // e.g. from a cached SQL view
corrections('cqto', vocab); // → ["cato"]: OR these into your tsquery / ILIKE
didYouMean('cqto', vocab); // → "cato", for the zero-result screen
然后重新排序数据库返回的行 createSearch - 一个排名
用于模拟清单和数据库结果.
为什么不在Postgres上做: pg_trgm 分数 kanye编号 :kayne 在0.2和0.2时
cqto编号 :cato 在任何有用的阈值下为0.4 fuzzystrmatch是因为
levenshtein 以两个编辑方式计算互换。 低调时使用三克调取
如果您喜欢, 请在此处决定字型 .
你自己的拼写规则.. normalize
SearchSpec.normalize(word) 在每句话,两边,在之后
标准折叠。 海蒂把瑞士德文读作人们的打字:"ie"作"i","i",
双倍字母为一,所以 gruzi mittenand 发现"Grüezi Mitenand". 留着吧
拼写;意思属于别处. expandQuery编号 :corrections 拿着
相同功能,所以词汇与索引一致。 分类预算仍为
WRITTEN一词:规则将"vill"变为"vil","vill"中的一个滑倒是:
仍然被原谅,就像任何四个字母.
已找到的数据库行 - rerank
rerank(rows, spec, query) 按打出的内容排列并保留行数
它不能在大地上
排行榜,按原顺序排列。 橙色猫 /api/search 军衔
Postgres的候选人是这样.
突出显示
hit.matches[field] 持有范围为原始文本( 类型匹配标记)
整个单词; 只有一个前缀的键. highlightQuery(text, q) 标记
以输入的单词开头的单词,用于未搜索的文本。 两者
返回平原部分——从不使用 HTML. snippet(text, ranges, { maxLength }) 削减
首个匹配的窗口的长长描述, 单词
边框,并用"..."将其切出,然后将范围重新放入其中.
反应( E)@bitbaum/searchkit/react(中文(简体) )
useSearchAsYouType(text, (q, signal) => fetch(...), { debounceMs: 100 })—— 说 每个按键键会中止它面前的请求; 对更年长者的后答 查询已删除 .<Highlight text ranges | query markClassName />- 无风格<mark>编号.
证明 typoCases 财务报告和审定财务报表 evaluate
const cases = typoCases(names); // every one-slip misspelling of every name
const report = await evaluate(cases, q => search(q).map(h => h.id));
// { successAt1, successAt3, mrr, zeroResults, misses }
滑动产生,而非想象:相邻的密钥(QWERTY和QWERTZ),a 扔了个字母,一个双倍字母,一个互换的对子. 把它放在CI和"一个滑倒" 仍然发现它" 失败的一天 它停止真实。 这个包是自己的套房 运行了571起此类案件,成功超过8个名称@1=1.
它不会做的
- 意为. "有人修我的自行车" 发现"Velo修补"是嵌入式的 任务(描述性查询,从不命名——密集检索输给 lexical) 名称由几十个点起。 将这种结果与对等排名合并 (k = 60) 如果添加的话.
- 警卫. 是否可以显示行是在其到达之前决定的 软件包。 一个内幕相配者在能见度门后没有任何业务.
- 电话. 施密特/施密特,迈尔/迈尔. 只对人名有用, 在其他地方有害;尚未建造.
来源
阿尔戈利亚打字容能和排名标准; 类型搜索参数; Meilisearch typo 内部; Damerau (1964年), Pollock & Zamora (1983年) 关于单人 编辑; Schulz & Mihov (2002) 关于列文斯泰因自動相機; SymSpell; Nielsen's 反应时间限制; Cormack, Clarke & Büttcher(SIGIR,2009年),关于RRF; 互联网档案馆的存檔,存档日期2013-12-20; Sciavolino等人(EMNLP 2021)关于密集检索和实体名称.