Repository navigation
fix(diacritics): compose Hangul back after stripping, so Korean search keeps working - #861
Open
wonjangcloud9 wants to merge 1 commit into
Open
wonjangcloud9 wants to merge 1 commit into
wonjangcloud9 wants to merge 1 commit into
Conversation
…h keeps working stripDiacritics NFD-normalizes its input to split off combining marks, but NFD also splits every Hangul syllable into two or three conjoining jamo, none of which is a diacritic, and nothing put them back together. With ignoreDiacritics on, a Korean query matched by shared jamo instead of by syllable: searching 감 among 감자, 검정, 곰, 김치, 강아지 returned all five instead of 감자. Match indices pointed into the longer decomposed text, so the highlight for 검색 in "한국어 검색 테스트" landed on 트. The stripped string is now NFC-normalized, which recomposes what NFD split but no rule removed. Latin results are unchanged (é still matches e), and precomposed Hangul keeps its length, so its match indices line up again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With
ignoreDiacritics: true, Korean search matches the wrong items and highlights the wrong text.stripDiacriticsNFD-normalizes its input to split off combining marks. NFD also decomposes every Hangul syllable into two or three conjoining jamo, which aren't diacritics and so are never stripped, and nothing recomposes them. The pattern and the text are compared as jamo sequences, so syllables that share a consonant fuzzily match each other. Match indices also come back as offsets into the longer decomposed string.Fix
stripDiacriticsnow ends with.normalize('NFC'). That recomposes whatever NFD split but no rule removed, which means Hangul. Combining marks are already gone by then, so Latin results don't change (éstill matchese). Precomposed Hangul keeps its original length, so its match indices line up with the original text again.Results with the built
dist/fuse.mjs,mainvs this branch:mainsearch('감'),ignoreDiacritics: true["감자","검정","곰","김치","강아지"]["감자"](same as without the option)검색in한국어 검색 테스트[[9,14]]→트[[4,5]]→검색Crème brûlée 레시피found bycreme brulee 레시피,threshold: 0Tests
New cases in
test/fuzzy-search.test.js:Searching Korean text ignoring diacriticschecks that a syllable gives the same results as without the option, and that match indices point at the matched syllables. Both fail onmainand pass here.npm run build,npm test(22 files, 452 tests) andnpm run lintpass. As in other fixes,dist/is rebuilt from the source change; each file differs only in thestripDiacriticsline.Performance
I measured search time over 10,000 items with
ignoreDiacritics: true, alternatingmain's and this branch'sdistover 15 trials each:Related
#840 remaps match indices for transformations that change string length, and touches this file. It doesn't change the Korean matching itself. This PR is a one-line change in
stripDiacritics, so whichever lands second should rebase easily.🤖 Generated with Claude Code