Multilingual Recipes & Limitations
This page provides production-ready tokenization recipes for English, Chinese, and Japanese full-text BM25 search, followed by important operational limitations to keep in mind.
Recipe 1: English with Stemming & Stopwords (wiki_tocken)
Combines Unicode word segmentation, NLTK stopwords removal, and Porter2 stemming with the built-in Wikipedia vocabulary (wiki_tocken):
Recipe 2: English Custom Corpus Model with Trigger
From the upstream pg_tokenizer examples, this workflow builds a domain-specific English vocabulary from your documents table and keeps embeddings updated automatically via trigger:
Recipe 3: Chinese Full-Text Search (jieba + Custom Model)
For Chinese text, combine the jieba pre-tokenizer (mode = "search", enable_hmm = true) with a custom corpus model trained on your table (demonstrated below using passages from Qian Zhongshu’s Fortress Besieged / 《围城》):
Recipe 4: Japanese Full-Text Search (lindera IPADIC)
When upgrading from Lindera 0.42 to 6.2, regenerate stored token arrays and rebuild their indexes because the IPADIC token IDs change. The dictionary configuration below remains supported; see the Lindera migration notes.
For Japanese text, create a Lindera IPADIC morphological model with iteration mark normalization, NFKC normalization, Japanese stop-tag filtering, and Katakana stemming (demonstrated below using passages from Natsume Sōseki’s I Am a Cat / 《吾輩は猫である》):
Operational Notes & Known Limitations
- Object Name Validation: All names for tokenizers, text analyzers, models, stopword dictionaries, and synonym dictionaries must contain only alphanumeric characters and underscores (
[A-Za-z0-9_]), and must not start with a digit. - Transaction Rollback & Per-Connection Object Cache: Each PostgreSQL connection caches
tokenizer,text_analyzer,model,stopwords, andsynonymobjects in backend memory (DashMap). Because this in-memory object pool is not tied to PostgreSQL’s transaction rollback callbacks, rolling back a transaction (ROLLBACK) reverts thetokenizer_catalogtables on disk, but the current connection’s in-memory cache still holds the created object. After aROLLBACK, explicitly call the correspondingdrop_*function (or reconnect) to clear the in-memory cache: - Preload Models Across Replicas:
add_preload_modelwrites the preload model list to the local$PGDATA/pg_tokenizerdirectory on the primary node. Because filesystem files outside PostgreSQL relations are not replicated via WAL, you should runadd_preload_modelon read replicas independently if you preload models there. - Memory Consumption of Built-in LLM Models: Models like
llmlingua2(~200 MB),gemma2b(~100 MB), andlinderaconsume significant memory. Always useadd_preload_modelin production so the model is loaded once in the postmaster process rather than duplicated per connection, or prefer a custom corpus model (create_custom_model) which uses only a few megabytes.