Skip to content

Instantly share code, notes, and snippets.

@chanmix51
Created November 6, 2012 10:35
Show Gist options
  • Save chanmix51/4023935 to your computer and use it in GitHub Desktop.
Save chanmix51/4023935 to your computer and use it in GitHub Desktop.
FT search with I18N in Postgresql
-- search
-- Perform a full text search in I18N using HStore
-- @param text $1 the language to search
-- @param text $2 the search string
-- @return int4 id The identifier of the searched table
-- @return float4 rank The ranking function result.
-- @return text excerpt An extract of text containing the searched words surrounded with <strong>.</strong>.
CREATE OR REPLACE FUNCTION test.search(text, text) RETURNS TABLE (id int4, rank float4, excerpt text) LANGUAGE sql AS $_$
SELECT
id,
ts_rank_cd(CAST(ft_name->$1 AS tsvector), query, 32) AS rank,
ts_headline($1::regconfig, description->$1, query, 'StartSel=<strong> StopSel=</strong>') AS excerpt
FROM
test.something,
to_tsquery($1::regconfig, $2) query
WHERE
ft_name->$1 @@ query
ORDER BY rank DESC
$_$
;
CREATE SCHEMA test;
CREATE TABLE test.something (id serial PRIMARY KEY, name hstore, ft_name hstore, description hstore);
CREATE OR REPLACE FUNCTION i18n_to_tsvector(test.something) RETURNS hstore LANGUAGE sql AS $_$
WITH
trans_name (culture, tsvector) AS (
SELECT
(a).key,
setweight(to_tsvector((a).key::regconfig, (a).value), 'A') || setweight(to_tsvector((b).key::regconfig, (b).value), 'B')
FROM
(SELECT each(($1).name)) name (a)
JOIN (SELECT each(($1).description)) description (b) ON (a).key = (b).key
)
SELECT
hstore(array_agg(culture), array_agg(tsvector::text))
FROM
trans_name
$_$
;
CREATE OR REPLACE FUNCTION before_each_insert_update() RETURNS TRIGGER LANGUAGE plpgsql AS $_$
BEGIN
NEW.ft_name := i18n_to_tsvector(NEW);
RETURN NEW;
END;
$_$
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment