我正在尝试在plpgsql中编写一个函数,该函数可使我高效地查询数据库。关于plpgsql的构建块不足,我无法完成/调试我的情况,如下所示:
案例:
我的数据库包含超过5000万条记录,其中包括文本,主题和元数据。
它只是结构化的描述数据,包含诸如
之类的句子
如果每个单词的拼写正确或正确无误,tsvector的“某个位置的棕色大箱子”或“一种令人难以置信的不同方法” tsvector将提供最高的匹配项,如果用户错过拼写,它将失败。我使用pg_tgrm作为后备,如果我相应地对结果进行排序,则可以使用相近性()或word_similarity()匹配
我已经使用pg_tgrm和tsvector索引了两列。 我希望能够有一个函数lookup(user_text,user_theme)通过匹配用户主题并输入到文本索引方法pg_tgrm或tsvector返回记录。
使用伪代码:
func lookup(user_input text, user_theme text) -> [score, record]:
var user_input_tsquery <- replace_char(user_input, ' ', ' & ')
if user_theme in database:
subdatabase <- A set of entries where database.theme = user_theme
var record <- subdatabase.tsvector = user_input_tsquery
var result_rank <- rank(subdatabase.tsvector = user_input_tsquery)
if record is not empty:
return [result_rank, record]
else
var record <- subdatabase.pg_tgrm = user_input
var simil <- similarity(subdatabase.pg_tgrm = user_input)
return [simil, record]
else
var record <- database.tsvector = user_input_tsquery
var result_rank <- rank(database.tsvector = user_input_tsquery)
if record is not empty:
return [result_rank, record]
else
var record <- database.pg_tgrm = user_input
var simil <- similarity(database.pg_tgrm = user_input)
return [simil, record]
plpgsql确实很难处理。 我曾尝试通过查询函数的一小部分来编写函数,但只是尝试调试如何编写返回值,或者是否需要TABLE或SETOF作为组合记录输出令人沮丧。
CREATE OR REPLACE FUNCTION lookup_test(user_input text, user_theme text) RETURNS TABLE AS $$
DECLARE user_input_ts text;
DECLARE ress TABLE;
DECLARE result TABLE(score double, summary text);
BEGIN
SELECT REPLACE(LOWER(user_input), ' ', ' & ') INTO user_input_ts;
CASE WHEN EXIST(SELECT * from database WHERE theme = user_theme)
THEN
CASE
SELECT * from database WHERE theme = user_theme INTO ress;
WHEN EXIST(SELECT least(ts_rank(ts_summary, user_input_ts, 32), 1.0) AS score, id_source
FROM ress
WHERE ts_sumnmary @@ to_tsquery('english', user_input_ts))
THEN RETURN ress;
SELECT tgrm_summary <-> user_input as score, *
FROM ress WHERE tgrm_summary % user_input
END CASE;
END;
END;
$$ LANGUAGE plpgsql;
我没有使用plpgsql的经验。我使用pg_tgrm和tsvector,因为前者是模糊兼容的,但速度较慢,而后者确实是快速的,但是需要精确的类型,所以我想处理是否可以得到将使用tsvector索引的智能结果,如果失败,请尝试使用pg_tgrm索引,此外,如果用户提供了主题,则可以将其用作减少要查找的条目数量的方式。