如何在PostgreSQL中建立有效的多重查询功能?

时间:2019-03-27 16:35:51

标签: postgresql plpgsql

我正在尝试在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索引,此外,如果用户提供了主题,则可以将其用作减少要查找的条目数量的方式。

0 个答案:

没有答案