Repository navigation
fix: preserve Unicode alphabetic marks in local text tokenization - #1575
leeshengis wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
chrikrah
left a comment
There was a problem hiding this comment.
@leeshengis from my perspective the tokenizer change can be merged. Local mode now tokenizes like 1.19.2 for MatchText and MatchTextAny, and the new tests fail on the base. I checked token boundaries only, so whether regex is acceptable as a new required native dependency stays open.
$ python -m pytest qdrant_client/local/tests/test_payload_filters.py -q # head c8f3642, CPython 3.12, regex 2026.9.29
23 passed in 1.10s
# payload_filters.py from b64c22e (dev), tests kept:
6 failed, 17 passed in 1.31s
# probe: unindexed "words" payloads 1 "क", 2 "की", 3 "aͅb", 4 "áb"; scroll ids
base b64c22e MatchText('क') -> [1, 2] MatchText('a b') -> [3, 4]
head c8f3642 MatchText('क') -> [1] MatchText('a b') -> [4]
server 1.19.2 MatchText('क') -> [1] MatchText('a b') -> [4] (MatchTextAny: same ids on head and server)
Has a maintainer agreed to that dependency, on the linked issue or elsewhere?

Summary
Fix local text tokenization dropping Unicode Alphabetic marks, which can make distinct words match the same filter.
For example, insert points whose
wordspayloads areकandकी, then scroll with:Before this change, local mode returns both points. Qdrant 1.19.2 returns only
क. The same mismatch occurs withMatchTextAny(text_any="क")andMatchPhrase(phrase="क").Rust's word tokenizer uses Unicode Alphabetic + Number. Python's
repattern[^\W_]+excludes Alphabetic marks such as Devanagari vowel signs and U+0345. Useregexproperty classes instead, and preserve tokenization-before-lowercasing. Not all combining marks are Alphabetic: U+0301 must remain a separator. No normalization is introduced.This adds the mandatory
regex>=2024.11.6dependency because stdlibredoes not support these Unicode properties;str.isalnum()has the same property gap. This adds a native-extension dependency (wheels where available, otherwise a build is needed). The lock update adds only this package, without updating existing packages.Unicode tables can differ between Python, regex and the server. This change fixes token boundaries; it does not promise complete parity across Unicode versions or change Python lowercasing. For example, Python 3.12's Unicode 15 tables do not lowercase the Unicode 16 U+1C89/U+1C8A pair like the tested server does.
Validation
016542aa5deb6c66380bb137badf73d54f742bde: public-API comparisons across local mode, REST and gRPC, unindexed fields and Word text indexes with phrase matchinggit diff --checkpassedAll Submissions
devChanges to Core Features