|
| 1 | +# graphile-pg-textsearch-plugin |
| 2 | + |
| 3 | +<p align="center" width="100%"> |
| 4 | + <img height="250" src="https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg" /> |
| 5 | +</p> |
| 6 | + |
| 7 | +<p align="center" width="100%"> |
| 8 | + <a href="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml"> |
| 9 | + <img height="20" src="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml/badge.svg" /> |
| 10 | + </a> |
| 11 | + <a href="https://github.com/constructive-io/constructive/blob/main/LICENSE"> |
| 12 | + <img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/> |
| 13 | + </a> |
| 14 | + <a href="https://www.npmjs.com/package/graphile-pg-textsearch-plugin"> |
| 15 | + <img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/constructive?filename=graphile%2Fgraphile-pg-textsearch-plugin%2Fpackage.json"/> |
| 16 | + </a> |
| 17 | +</p> |
| 18 | + |
| 19 | +**`graphile-pg-textsearch-plugin`** enables auto-discovered BM25 ranked full-text search for PostGraphile v5 schemas using [pg_textsearch](https://github.com/timescale/pg_textsearch). |
| 20 | + |
| 21 | +## Installation |
| 22 | + |
| 23 | +```sh |
| 24 | +npm install graphile-pg-textsearch-plugin |
| 25 | +``` |
| 26 | + |
| 27 | +## Features |
| 28 | + |
| 29 | +- **Auto-discovery**: Finds all text columns with BM25 indexes automatically — zero configuration |
| 30 | +- **Condition fields**: `bm25<Column>` condition inputs accepting `{ query, threshold? }` for BM25 ranked search |
| 31 | +- **Score fields**: `bm25<Column>Score` computed fields returning BM25 relevance scores (negative values, more negative = more relevant) |
| 32 | +- **OrderBy**: `BM25_<COLUMN>_SCORE_ASC/DESC` enum values for sorting by relevance |
| 33 | +- Works with PostGraphile v5 preset/plugin pipeline |
| 34 | + |
| 35 | +## Usage |
| 36 | + |
| 37 | +### With Preset (Recommended) |
| 38 | + |
| 39 | +```typescript |
| 40 | +import { Bm25SearchPreset } from 'graphile-pg-textsearch-plugin'; |
| 41 | + |
| 42 | +const preset = { |
| 43 | + extends: [ |
| 44 | + // ... your other presets |
| 45 | + Bm25SearchPreset(), |
| 46 | + ], |
| 47 | +}; |
| 48 | +``` |
| 49 | + |
| 50 | +### With Plugin Directly |
| 51 | + |
| 52 | +```typescript |
| 53 | +import { Bm25CodecPlugin, Bm25SearchPlugin } from 'graphile-pg-textsearch-plugin'; |
| 54 | + |
| 55 | +const preset = { |
| 56 | + plugins: [ |
| 57 | + Bm25CodecPlugin, |
| 58 | + Bm25SearchPlugin(), |
| 59 | + ], |
| 60 | +}; |
| 61 | +``` |
| 62 | + |
| 63 | +### GraphQL Query |
| 64 | + |
| 65 | +```graphql |
| 66 | +query SearchArticles($search: Bm25SearchInput!) { |
| 67 | + articles(condition: { bm25Body: $search }) { |
| 68 | + nodes { |
| 69 | + id |
| 70 | + title |
| 71 | + body |
| 72 | + bm25BodyScore |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +Variables: |
| 79 | + |
| 80 | +```json |
| 81 | +{ |
| 82 | + "search": { |
| 83 | + "query": "postgres full text search", |
| 84 | + "threshold": -0.5 |
| 85 | + } |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +### OrderBy |
| 90 | + |
| 91 | +```graphql |
| 92 | +query SearchArticlesSorted($search: Bm25SearchInput!) { |
| 93 | + articles( |
| 94 | + condition: { bm25Body: $search } |
| 95 | + orderBy: BM25_BODY_SCORE_ASC |
| 96 | + ) { |
| 97 | + nodes { |
| 98 | + id |
| 99 | + title |
| 100 | + bm25BodyScore |
| 101 | + } |
| 102 | + } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +## Requirements |
| 107 | + |
| 108 | +- PostgreSQL with [pg_textsearch](https://github.com/timescale/pg_textsearch) extension installed |
| 109 | +- PostGraphile v5 (rc.5+) |
| 110 | +- A BM25 index on the text column(s) you want to search: |
| 111 | + |
| 112 | +```sql |
| 113 | +CREATE INDEX articles_body_idx ON articles USING bm25(body) |
| 114 | + WITH (text_config='english'); |
| 115 | +``` |
| 116 | + |
| 117 | +## Testing |
| 118 | + |
| 119 | +```sh |
| 120 | +# requires pyramation/postgres:17 Docker image with pg_textsearch pre-installed |
| 121 | +pnpm --filter graphile-pg-textsearch-plugin test |
| 122 | +``` |
| 123 | + |
0 commit comments