{"id":19458514,"url":"https://github.com/postgrespro/tsexact","last_synced_at":"2025-06-15T00:07:12.605Z","repository":{"id":149601153,"uuid":"26425905","full_name":"postgrespro/tsexact","owner":"postgrespro","description":"PostgreSQL fulltext search addon","archived":false,"fork":false,"pushed_at":"2018-03-21T16:11:20.000Z","size":13,"stargazers_count":12,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-09T15:57:36.714Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/postgrespro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-10T07:33:40.000Z","updated_at":"2025-03-05T12:08:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"835c6471-c785-4024-b82d-8f99a1fa04f3","html_url":"https://github.com/postgrespro/tsexact","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/postgrespro/tsexact","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postgrespro%2Ftsexact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postgrespro%2Ftsexact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postgrespro%2Ftsexact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postgrespro%2Ftsexact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/postgrespro","download_url":"https://codeload.github.com/postgrespro/tsexact/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postgrespro%2Ftsexact/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259901382,"owners_count":22929224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T17:27:24.584Z","updated_at":"2025-06-15T00:07:12.584Z","avatar_url":"https://github.com/postgrespro.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"TSExact – PostgreSQL fulltext search addon\n==========================================\n\nIntroduction\n------------\n\nTSExact – is a PostgreSQL extension with various helper function for fulltext\nsearch.  Basically TSExact contains functions which emulate phrase search on\nPostgreSQL versions 9.5 and lower.  If you're using PostgreSQL 9.6 and higher\nyou should consider using builtin phrase search rather than TSExact.\n\n\nAuthors\n-------\n\n * Alexander Korotkov \u003caekorotkov@gmail.com\u003e, Postgres Professional, Moscow, Russia\n\nAvailability\n------------\n\nTSExact is released as an extension and not available in default PostgreSQL\ninstallation. It is available from\n[github](https://github.com/postgrespro/tsexact)\nunder the same license as\n[PostgreSQL](http://www.postgresql.org/about/licence/)\nand supports PostgreSQL 9.0+.\n\nInstallation\n------------\n\nBefore build and install TSExact you should ensure following:\n    \n * PostgreSQL version is 9.0 or higher.\n * You have development package of PostgreSQL installed or you built\n   PostgreSQL from source.\n * Your PATH variable is configured so that pg\\_config command available.\n    \nTypical installation procedure may look like this:\n    \n    $ git clone https://github.com/postgrespro/tsexact.git\n    $ cd tsexact\n    $ make USE_PGXS=1\n    $ sudo make USE_PGXS=1 install\n    $ make USE_PGXS=1 installcheck\n    $ psql DB -c \"CREATE EXTENSION tsexact;\"\n\nUsage\n-----\n\nTSExact offers various helper functions which are listed in the table below. In particular these functions could be used for simple fulltext search.\n\n|          Function                                                 | Return type |                      Description                           |\n| ----------------------------------------------------------------- | ----------- | ---------------------------------------------------------- |\n| ts_exact_match(document tsvector, fragment tsvector)              | bool        | Check if given fragment is present in document             |\n| ts_exact_match(document tsvector, fragment tsvector, weight text) | bool        | Check if given fragment is present in document with weight |\n| ts_squeeze(document tsvector)                                     | tsvector    | Remove empty positions from document                       |\n| setweight(query tsquery, weight text)                             | tsquery     | Assign weight for each lexeme in tsquery                   |\n| poslen(documents tsvector)                                        | integer     | Return total number of positions in document               |\n\n`ts_exact_match(tsvector, tsvector)` function checks if given fragment appears in given document at some offset.\n\n    # SELECT ts_exact_match('cat:3 fat:2 sad:4'::tsvector, 'cat:2 fat:1 sad:4'::tsvector);\n     ts_exact_match \n    ----------------\n     f\n    (1 row)\n\n    # SELECT ts_exact_match('cat:3 fat:2 sad:5'::tsvector, 'cat:2 fat:1 sad:4'::tsvector);\n     ts_exact_match \n    ----------------\n     t\n    (1 row)\n\n`ts_exact_match(tsvector, tsvector)` ignores lexemes weights. `ts_exact_match(tsvector, tsvector, text)` only finds fragments in given weight of document. Weights of fragment are always ignored.\n\n    # SELECT ts_exact_match('cat:3 fat:2 sad:5'::tsvector, 'cat:2 fat:1 sad:4'::tsvector, 'ABC');\n     ts_exact_match \n    ----------------\n     f\n    (1 row)\n\n    # SELECT ts_exact_match('cat:3A fat:2B sad:5C'::tsvector, 'cat:2 fat:1 sad:4'::tsvector, 'ABC');\n     ts_exact_match \n    ----------------\n     t\n    (1 row)\n\nSince tsvectors could contain gaps in position numbering it's suitable to remove gaps using `ts_squeeze(tsvector)`.\n\n    # SELECT ts_squeeze('cat:2,9 fat:1,6 sad:4'::tsvector);\n             ts_squeeze\n    -----------------------------\n     'cat':2,5 'fat':1,4 'sad':3\n    (1 row)\n\nFulltext search indexes doesn't support `ts_exact_match()` functions. Thus, it's useful to combine `ts_exact_match()` with `tsvector @@ tsquery` expression in order to use indexed search. Therefore, complete example of phrase search may be following.\n\n    -- Calculate tsvector using ts_squeeze() function in order to remove gaps in\n    -- lexemes offsets.\n    UPDATE tt SET ti =\n        ts_squeeze(\n            setweight(to_tsvector(coalesce(title,'')), 'A')    ||\n            setweight(to_tsvector(coalesce(keyword,'')), 'B')  ||\n            setweight(to_tsvector(coalesce(abstract,'')), 'C') ||\n            setweight(to_tsvector(coalesce(body,'')), 'D'));\n    \n    -- Search for phrase. \"tsvector @@ tsquery\" operator is used for phrase search,\n    -- ts_exact_match() function is used to recheck an exact phrase match.\n    SELECT *\n    FROM tt\n    WHERE tt.ti @@ plainto_tsquery('fat rat') AND\n          ts_exact_match(tt.ti, ts_squeeze(to_tsvector('fat rat')));\n\n\n`setweight(tsquery, text)` assigns given weight to each lexeme of tsquery.\n\n    # SELECT setweight('fat:A \u0026 (cat:B | rat:C)'::tsquery, 'CD');\n                 setweight\n    ------------------------------------\n     'fat':CD \u0026 ( 'cat':CD | 'rat':CD )\n    (1 row)\n\n`poslen(tsvector)` returns total number of lexeme positions in tsvector.\n\n    # SELECT poslen('cat:3,4,5,9,10 fat:1,2,6,7,8'::tsvector);\n     poslen\n    --------\n         10\n    (1 row)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostgrespro%2Ftsexact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpostgrespro%2Ftsexact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostgrespro%2Ftsexact/lists"}