如何在PostgreSQL中构建高效的多查询函数?
我正在尝试用plpgsql编写一个函数,使我能够高效地查询数据库。plpgsql的构建块不足,无法完成/调试我的案例,具体如下: 案例: 我的数据库包含5000多万条记录,其中包括文本、主题和元数据。如何在PostgreSQL中构建高效的多查询函数?,postgresql,plpgsql,Postgresql,Plpgsql,我正在尝试用plpgsql编写一个函数,使我能够高效地查询数据库。plpgsql的构建块不足,无法完成/调试我的案例,具体如下: 案例: 我的数据库包含5000多万条记录,其中包括文本、主题和元数据。 它只是非常结构化的描述数据,包含以下语句 如果每个单词拼写正确,不管顺序如何,一个大的棕色主干或一个令人难以置信的不同方法tsvector将提供最高的匹配条目,如果用户拼写错误,它将失败。我使用pg_tgrm作为它的回退,如果我对结果进行相应排序,它将使用相似性或单词相似性进行匹配 我使用pg_t
它只是非常结构化的描述数据,包含以下语句 如果每个单词拼写正确,不管顺序如何,一个大的棕色主干或一个令人难以置信的不同方法tsvector将提供最高的匹配条目,如果用户拼写错误,它将失败。我使用pg_tgrm作为它的回退,如果我对结果进行相应排序,它将使用相似性或单词相似性进行匹配 我使用pg_tgrm和tsvector为两列建立了索引。 我希望能够有一个函数lookupuser_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索引,此外,如果用户提供主题,然后用它来减少要查找的条目数量。您应该从定义确切的需求开始。全文搜索和相似性匹配是完全不同的。成功匹配的条件是什么?它只是非常结构化的描述数据。数据库中包含一些句子,例如某个位置的一个大棕色主干,或者一种难以置信的不同方法。如果每个单词拼写正确,无论顺序如何,tsvector都将提供最高匹配条目,如果用户拼写错误,它将失败。我使用pg_tgrm作为它的后备方法,如果我按照顺序排列结果,它将使用相似性或单词相似性进行匹配。您不需要使用EXISTSELECT*from database WHERE theme=user_theme然后->>尝试选择不存在的记录是犯罪的。这看起来不像是有效的PL/pgSQL。声明ress表;是一个语法错误。您不是在使用常规的PostgreSQL吗?您应该从定义确切的需求开始。全文搜索和相似性匹配是完全不同的。成功匹配的条件是什么?它只是非常结构化的描述数据。数据库中包含一些句子,例如某个位置的一个大棕色主干,或者一种难以置信的不同方法。如果每个单词拼写正确,无论顺序如何,tsvector都将提供最高匹配条目,如果用户拼写错误,它将失败。我使用pg_tgrm作为它的后备方法,如果我按照顺序排列结果,它将使用相似性或单词相似性进行匹配。您不需要使用EXISTSELECT*from database WHERE theme=user_theme然后->>尝试选择不存在的记录是犯罪的。这看起来不像是有效的PL/pgSQL。声明ress表;是一个语法错误。你没有使用常规的PostgreSQL吗?