CREATE DATABASE "tsearch2"
WITH ENCODING = 'UTF8' ;
CREATE TABLE "news"
(
"NewsId" Serial NOT NULL ,
"Title" Varchar (1024) NOT NULL ,
"MetaKeywords" Varchar (2048),
"MetaDescription" Varchar (1024),
"Content" Text NOT NULL ,
primary key ("newsId")
);
INSERT INTO "news" ("title", "metaKeywords", "metaDescription", "content")
VALUES ( 'Test news' , 'news, article' , 'Test news for search' , 'Hello world' );
CREATE TEXT SEARCH DICTIONARY mydict_russian_ispell (
TEMPLATE = ispell,
DictFile = russian,
AffFile = russian,
StopWords = russian
);
CREATE TEXT SEARCH CONFIGURATION public. Mydict_ru (PARSER = default );
COMMENT ON TEXT SEARCH CONFIGURATION public .mydict IS 'conf. for mydict ru ' ;
')
ALTER TEXT SEARCH CONFIGURATION mydict ADD MAPPING
FOR email, url, url_path, host , file , version,
sfloat, float , int , uint,
numword, hword_numpart, numhword
WITH simple;
ALTER TEXT SEARCH CONFIGURATION mydict ADD MAPPING
FOR word, hword_part, hword
WITH mydict_russian_ispell;
ALTER TABLE "news" ADD COLUMN fts_news tsvector;
UPDATE "news" SET fts_news =
setweight ( coalesce (to_tsvector ( 'mydict_ru' , "title"), '' ), 'A' ) ||
setweight ( coalesce (to_tsvector ( 'mydict_ru' , "metaKeywords"), '' ), 'B' ) ||
setweight ( coalesce (to_tsvector ( 'mydict_ru' , "metaDescription"), '' ), 'C' ) ||
setweight ( coalesce (to_tsvector ( 'mydict_ru' , "content"), '' ), 'D' );
CREATE INDEX news_fts_idx ON "news" USING gist (fts_news);
vacuum analyze "news";
SELECT
"NewsId",
ts_headline ( 'mydict_ru' , "title", q) as "title",
rank
FROM (
SELECT
"NewsId",
"Title",
q,
ts_rank (fts_news, q) as rank
FROM "news", plainto_tsquery ( 'mydict_ru' , 'news' ) q
WHERE fts_news @@ q
ORDER BY rank DESC
) AS foo;
CREATE OR REPLACE FUNCTION "updateNewsFTS" () RETURNS " trigger " AS '
DECLARE bUpdate boolean;
BEGIN
bUpdate = false;
IF (TG_OP = ' ' INSERT ' ') THEN
bUpdate: = true;
ELSEIF (TG_OP = ' ' UPDATE ' ') THEN
IF NEW.title! = OLD.title OR NEW.content! = OLD.content OR NEW. "MetaKeywords"! = OLD. "MetaKeywords" OR NEW. "MetaDescription"! = OLD. "MetaDescription" THEN
bUpdate: = true;
END IF;
END IF;
IF bUpdate = TRUE THEN
RAISE NOTICE ' ' UPDATE ' ';
new.fts_news: = setweight (coalesce (to_tsvector (' ' mydict_ru ' ', new.title), ' ' ' '), ' ' A ' ') ||
setweight (coalesce (to_tsvector (' ' mydict_ru ' ', new. "metaKeywords"), ' ' ' ', ' ' B ' ') ||
setweight (coalesce (to_tsvector (' ' mydict_ru ' ', new. "metaDescription"), ' ' ' ', ' ' C ' ') ||
setweight (coalesce (to_tsvector (' ' mydict_ru ' ', new.content), ' ' ' '), ' ' D ' ');
END IF;
RETURN NEW;
END;
' LANGUAGE ' plpgsql ' VOLATILE;
CREATE TRIGGER "newsFTSTrigger"
BEFORE INSERT OR UPDATE ON "news"
FOR EACH ROW EXECUTE PROCEDURE “updateNewsFTS” ();
SELECT
"Id"
"Type",
ts_headline ( 'mydict_ru' , "title", q) as "title",
( CASE WHEN trim ("foreword") = '' THEN ts_headline ( 'mydict_ru' , "content", q)
ELSE ts_headline ( 'mydict_ru' , "foreword", q) END ) as "body",
"ResourceTypes",
rank
FROM (
SELECT
"Id"
"Type",
"Title",
Foreword
"Content",
"ResourceTypes",
q,
ts_rank (fts_vector, q) as rank
FROM "getSearchItems", plainto_tsquery ( 'mydict_ru' , 'physics' ) q
WHERE fts_vector @@ q
ORDER BY rank DESC
) AS foo;
SELECT *
, ( SELECT position ( lower ( 'physics' ) in lower (" search ". "Title")) as "pos"
EXCEPT SELECT 0 as "pos") as "titlePosition"
, ( select position ( lower ( 'physics' ) in lower (" search ". "metaKeywords")) as "pos"
EXCEPT SELECT 0 as "pos") as "metaKeywordsPosition"
, ( SELECT position ( lower ( 'physics' ) in lower (" search ". "MetaDescription")) as "pos"
EXCEPT SELECT 0 as "pos") as "metaDescriptionPosition"
, ( SELECT position ( lower ( 'physics' ) in lower (" search ". "Foreword")) as "pos"
EXCEPT SELECT 0 as "pos") as "forewordPosition"
, ( SELECT position ( lower ( 'physics' ) in lower (" search ". "Content")) as "pos"
EXCEPT SELECT 0 as "pos") as "contentPosition"
FROM (
SELECT
"Id"
"Type",
"Title",
"MetaKeywords",
"MetaDescription",
Foreword
"Content"
FROM "getSearchItems"
WHERE ( lower ("title") ~ lower ( '(. *)' || physics' || '(. *)' )
or lower ("metaKeywords") ~ lower ( '(. *)' || physics' || '(. *)' )
or lower ("metaDescription") ~ lower ( '(. *)' || physics' || '(. *)' )
or lower ("foreword") ~ lower ( '(. *)' || 'physics' || '(. *)' )
or lower ("content") ~ lower ( '(. *)' || physics' || '(. *)' ))
) as " search "
ORDER BY "type" ASC
, "TitlePosition" ASC
, "MetaKeywordsPosition" ASC
, "MetaDescriptionPosition" ASC
, "ForewordPosition" ASC
, "ContentPosition" ASC ;
CREATE TEXT SEARCH DICTIONARY english_ispell (
TEMPLATE = ispell,
DictFile = english,
AffFile = english,
StopWords = english
);
ALTER TEXT SEARCH CONFIGURATION mydict ADD MAPPING
FOR asciiword
WITH english_ispell;
Source: https://habr.com/ru/post/30533/
All Articles