#3025·typesense

与 locale 同义词:"th"在词汇边界处包含 SARA AM (U+0E33) 时永远不匹配

作者: thebossza101创建于 2026年8月15日更新于 2026年9月1日
标签bug

Description When a synonym term is written with the Thai character SARA AM ( , U+0E33 ) and the synonym item has locale: "th", the synonym never matches — not even for a single-token query typed exactly as the synonym was defined. The same synonym works correctly when locale is omitted, and it also works if the synonym term is stored with SARA AM written in its decomposed form ( U+0E4D + U+0E32). This suggests the query token is normalized/decomposed under the th locale, but the synonym term is not normalized the same way when it is stored or looked up, so the two can never meet. ## Environment - Typesense v30.2, self-hosted (GET /debug{"state":1,"version":"30.2"}) - Reproduced consistently across many runs on a fresh collection + fresh synonym set ## Steps to reproduce Thai is written as \\\\uXXXX (body) and percent escapes (query string) so the script is shell-encoding independent. The term used is น้ำหอม — "perfume". bash TS=http://localhost:8108 KEY=xyz # 1. Synonym set: "น้ำหอม" <-> "perfume", with locale: th curl -s -X PUT "$TS/synonym_sets/bug_set" -H "X-TYPESENSE-API-KEY: $KEY" -H 'Content-Type: application/json' -d '{"items":[{"id":"s","synonyms":["\u0e19\u0e49\u0e33\u0e2b\u0e2d\u0e21","perfume"],"locale":"th"}]}' # 2. Collection with a th-locale string field curl -s -X POST "$TS/collections" -H "X-TYPESENSE-API-KEY: $KEY" -H 'Content-Type: application/json' -d '{"name":"bug","synonym_sets":["bug_set"],"fields":[{"name":"t","type":"string","locale":"th"}]}' # 3. One document containing the English side of the synonym curl -s -X POST "$TS/collections/bug/documents/import?action=create" -H "X-TYPESENSE-API-KEY: $KEY" -d '{"t":"item perfume"}' # 4. Query with the Thai side of the synonym curl -s "$TS/collections/bug/documents/search?q=%E0%B8%99%E0%B9%89%E0%B8%B3%E0%B8%AD%E0%B8%A1&query_by=t&drop_tokens_threshold=0" -H "X-TYPESENSE-API-KEY: $KEY"

Step 1 round-trips correctly — GET /synonym_sets/bug_set returns the term unchanged, so the term is stored fine; only lookup fails. Drop "locale":"th" from step 1 and step 2 and the same script returns found: 1.

synonym term stored as query typed as locale found
น้ำหอม composed (U+0E33) น้ำหอม composed (unset) 1
น้ำหอม composed (U+0E33) น้ำหอม composed th 0
น้ําหอม decomposed (U+0E4D U+0E32) น้ำหอม composed th 1
น้ำหอม composed (U+0E33) น้ําหอม decomposed th 0
น้ําหอม decomposed (U+0E4D U+0E32) น้ําหอม decomposed th 1

The query form does not matter. Only the stored synonym form does — a synonym term containing …

内容来源: typesense/typesense