zhparser

repository·master·Indexed 21 days ago

https://github.com/amutu/zhparser

A PostgreSQL extension for full-text search of Mandarin Chinese. It utilizes the SCWS (Simple Chinese Word Segmentation) engine to provide word segmentation within the PostgreSQL text search framework. It supports custom dictionaries via TXT files or the zhprs_custom_word table, and provides configuration options for punctuation handling, memory loading, and segmentation behavior.

Tokens
2.3K
Snippets
6
Records
8
Agent score
25%

What's inside zhparser

  1. Manage custom dictionaries via TXT files

    master

    You can add custom dictionaries to zhparser by placing files in the share/tsearch_data directory. zhparser supports .txt (text) and .xdb (binary) formats.

    TXT Dictionary Format

    Each line represents one record with up to 4 fields separated by spaces or tabs: 词语 (Word) | TF | IDF | 词性 (Part of Speech)

    • Comments: Lines starting with # or ; are ignored.
    • Defaults: If TF and IDF are omitted, they default to 1.0. If 词性 is omitted, it defaults to @.
    • Deletion: To mark a word as invalid (even if it exists in core libraries), set its part of speech to !.
    • Priority: Multiple dictionaries in zhparser.extra_dicts are processed in order of increasing priority (left to right).
  2. Use zhparser for Full-Text Search

    master

    To use zhparser for Chinese text search, you must create a text search configuration that uses the zhparser parser and map token types to a dictionary (usually simple).

    Basic Workflow

    1. Create Extension: CREATE EXTENSION zhparser;
    2. Create Configuration: CREATE TEXT SEARCH CONFIGURATION <name> (PARSER = zhparser);
    3. Add Mappings: ALTER TEXT SEARCH CONFIGURATION <name> ADD MAPPING FOR n,v,a,i,e,l WITH simple;

    Available Functions

    • ts_parse('zhparser', 'text'): Returns a table of tokid and token for the given text.
    • to_tsvector('<config>', 'text'): Converts text into a tsvector using the specified configuration.
    • to_tsquery('<config>', 'query'): Converts a string into a tsquery using the specified configuration.
    -- Setup
    CREATE EXTENSION zhparser;
    CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
    ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;
    
    -- Parsing
    SELECT * FROM ts_parse('zhparser', 'hello world! 2010年保障房建设');
    
    -- Search
    SELECT to_tsvector('testzhcfg', '今年保障房新开工数量虽然有所下调');
    SELECT to_tsquery('testzhcfg', '保障房资金压力');
  3. Run zhparser regression tests

    master

    Use the regress/regress.sh wrapper to run regression tests against different PostgreSQL versions. This provides a fast signal for whether C code changes have broken existing functionality.

    Available Commands

    • check: Runs tests against the default PostgreSQL version (PG 16).
    • check <version>: Runs tests against a specific PostgreSQL version (e.g., 17).
    • matrix: Runs tests against multiple PostgreSQL versions (16, 17, and 18) sequentially.
    • shell <version>: Drops you into a shell inside a container running a test cluster for that specific PostgreSQL version. This allows you to run manual queries via psql against the running instance.
    # From the project root.
    regress/regress.sh check          # PG 16 by default
    regress/regress.sh check 17       # PG 17
    regress/regress.sh matrix         # 16 + 17 + 18
    
    # Drop into a shell with the test cluster running:
    regress/regress.sh shell 16
    
    # (inside the container)
    psql -h /tmp -p 55432 -U postgres
  4. Install zhparser from source

    master

    To install zhparser on a system with PostgreSQL 9.2 or higher, follow these steps:

    1. Install SCWS

    zhparser is based on SCWS (Simple Chinese Word Segmentation). Download and install it first:

    wget -q -O - http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 | tar xf -
    cd scws-1.2.3
    ./configure
    make install

    Note: On FreeBSD 10+, use --with-pic during ./configure.

    2. Build and Install zhparser

    Clone the repository and compile it. You can specify SCWS_HOME if SCWS is not in /usr/local and PG_CONFIG if you have multiple PostgreSQL versions installed.

    git clone https://github.com/amutu/zhparser.git
    cd zhparser
    # Optional: set SCWS_HOME or PG_CONFIG
    SCWS_HOME=/usr/local PG_CONFIG=/usr/lib/postgresql/9.5/bin/pg_config make && make install

    3. Create the Extension

    Run the following command in your PostgreSQL instance:

    CREATE EXTENSION zhparser;
    wget -q -O - http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 | tar xf -
    cd scws-1.2.3 ; ./configure ; make install
    
    git clone https://github.com/amutu/zhparser.git
    cd zhparser
    make && make install
    
    # Then in psql
    psql dbname superuser -c 'CREATE EXTENSION zhparser'
  5. Quick Start with Docker

    master

    You can quickly experience zhparser using a pre-configured Docker container. This method handles the installation of PostgreSQL and the zhparser extension automatically.

    1. Run the container: docker run --name pgzhparser -d -e POSTGRES_PASSWORD=somepassword zhparser/zhparser:bookworm-16
    2. Login to the database: docker exec -it pgzhparser psql postgres postgres
    3. Initialize the extension and test parsing.
    # Run the container
    docker run --name pgzhparser -d -e POSTGRES_PASSWORD=somepassword zhparser/zhparser:bookworm-16 
    
    # Login to postgres
    docker exec -it pgzhparser psql postgres postgres
    
    # Inside psql, setup and test
    CREATE EXTENSION zhparser;
    CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
    ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;
    SELECT * FROM ts_parse('zhparser', 'hello world! 2010年保障房建设在全国范围内获全面启动');
  6. Refresh expected regression test output

    master

    If you have made changes that intentionally alter the output of the parser (such as fixing bugs in lex-type truncation), you must regenerate the expected output files. The refresh command runs the tests and writes the new results from results/*.out back into your local expected/ directory.

    Workflow:

    1. Run the refresh command for your target version.
    2. Use git diff to review the changes to the expected/ directory to ensure they are correct.
    regress/regress.sh refresh 16
    git diff expected/
  7. Configure zhparser settings

    master

    zhparser provides several configuration options to control dictionary loading and segmentation behavior. Most options default to false.

    Note: zhparser.extra_dicts and zhparser.dict_in_memory must be set before the backend starts (e.g., in the configuration file and then reloaded). Other options can be set in the current session.

    OptionDescription
    zhparser.punctuation_ignoreIgnore all punctuation and special symbols
    zhparser.seg_with_dualityAutomatically aggregate idle text using two-character segmentation
    zhparser.dict_in_memoryLoad the entire dictionary into memory
    zhparser.multi_shortShort word composition
    zhparser.multi_dualityScattered character duality composition
    zhparser.multi_zmainImportant single character composition
    zhparser.multi_zallAll single character composition
    zhparser.extra_dictsPath to custom dictionaries (comma-separated, e.g., 'dict_extra.txt,mydict.xdb')
  8. Manage custom words via SQL (zhprs_custom_word)

    master

    For database-level custom word management (requires superuser permissions), zhparser provides a table-based approach. This is more flexible for dynamic updates than file-based dictionaries.

    Workflow

    1. Insert a word: INSERT INTO zhparser.zhprs_custom_word VALUES('word_text');
    2. Delete a word: INSERT INTO zhprs_custom_word(word, attr) VALUES('word_text', '!');
    3. Sync changes: After modifying the table, you must run SELECT sync_zhprs_custom_word(); and then reconnect to the database for changes to take effect in the parser.

    To inspect the table structure (which supports TD and IDF fields), use \d zhprs_custom_word in psql.

    -- Add a custom word
    INSERT INTO zhparser.zhprs_custom_word VALUES('资金压力');
    
    -- Sync the changes
    SELECT sync_zhprs_custom_word();
    
    -- Note: You must reconnect to the database after syncing
    
    -- Delete a word
    INSERT INTO zhprs_custom_word(word, attr) VALUES('资金压力', '!');