More SqlDelight (Text Search with PostgreSql)

Support for TSVECTOR data type in SqlDelight 2.1.0-SNAPSHOT

Example

Add Full Text Search to your database.

Repository

https://github.com/griffio/sqldelight-postgres-textsearch/blob/master/README.md

Schema

CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE TABLE PgWeb (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
title TEXT,
body TEXT,
last_mod_date TIMESTAMPTZ
);

Add a stored generated column to automatically update from the source data. This example is a concatenation of title and body, using coalesce to ensure that one field will still be indexed when the other is NULL - textsearch-tables

ALTER TABLE pgweb
ADD COLUMN textsearchable_index_col TSVECTOR
GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;

Create a GIN index to speed up the search

The pgtrgm module provides GiST and GIN index operator classes that allow you to create an index over a text column for the purpose of very fast similarity searches

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));
CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);
CREATE INDEX pgweb_body_trgm ON pgweb USING GIST (body gist_trgm_ops(siglen=16));

Queries

bodySearchable:
SELECT title
FROM pgweb
WHERE to_tsvector('english', body) @@ to_tsquery('english', ?)
ORDER BY last_mod_date DESC
LIMIT 10;

titleBodySearchable:
SELECT title
FROM pgweb
WHERE to_tsvector(title || ' ' || body) @@ to_tsquery(?)
ORDER BY last_mod_date DESC
LIMIT 10;

textSearchable:
SELECT title
FROM pgweb
WHERE textsearchable_index_col @@ to_tsquery(?)
ORDER BY last_mod_date DESC
LIMIT 10;

regexSearch:
SELECT title
FROM pgweb
WHERE body LIKE '%' || ? || '%'
ORDER BY last_mod_date DESC
LIMIT 10;

Application

    sample.pgWebQueries.bodySearchable("neutrino & sun")
        .executeAsList().also(::println)

    sample.pgWebQueries.titleBodySearchable("neutrino | sun")
        .executeAsList().also(::println)

    sample.pgWebQueries.textSearchable("neutrino | gravity")
        .executeAsList().also(::println)

    sample.pgWebQueries.regexSearch("atomic")
        .executeAsList().also(::println)