【问题标题】:PostgreSQL: Find sentences closest to a given sentencePostgreSQL:查找最接近给定句子的句子
【发布时间】:2025-12-20 03:00:10
【问题描述】:

我有一张带有句子标题的图片表。给定一个新句子,我想根据新句子与存储的旧句子的接近程度来找到与其最匹配的图像。

我知道我可以将@@ 运算符与to_tsquery 一起使用,但tsquery 接受特定单词作为查询。

一个问题是我不知道如何将给定的句子转换为有意义的查询。句子可能有标点和数字。

但是,我也觉得某种余弦相似度是我需要的,但我不知道如何从 PostgresQL 中得到它。我正在使用最新的 GA 版本,如果可以解决我的问题,我很乐意使用开发版本。

【问题讨论】:

    标签: postgresql full-text-search tf-idf cosine-similarity


    【解决方案1】:

    全文搜索 (FTS)

    您可以使用 plainto_tsquery() 到 (per documentation) ...

    产生tsquery忽略标点符号

    SELECT plainto_tsquery('english', 'Sentence: with irrelevant words (and punctuation) in it.')
    
     plainto_tsquery
    ------------------
     'sentenc' & 'irrelev' & 'word' & 'punctuat'
    

    像这样使用它:

    SELECT *
    FROM   tbl
    WHERE  to_tsvector('english', sentence) @@ plainto_tsquery('english', 'My new sentence');
    

    但这仍然相当严格,并且只能提供非常有限的相似性容忍度。

    三元组相似度

    可能更适合搜索相似性,甚至在一定程度上克服了拼写错误。

    安装附加模块pg_trgm,创建一个GiST索引并在最近邻搜索中使用similarity operator %

    基本上,在 sentence 上有一个三元组 GiST 索引:

    -- SELECT set_limit(0.3);  -- adjust tolerance if needed
    
    SELECT *
    FROM   tbl
    WHERE  sentence % 'My new sentence'
    ORDER  BY sentence <-> 'My new sentence'
    LIMIT  10;
    

    更多:

    两者结合

    您甚至可以结合 FTS 和 trigram 相似性:

    【讨论】:

      【解决方案2】:

      这是一个很晚的答案,但我会添加以防有人遇到。如果你在词尾加上“:*”,就会出现类似的词。 样本: JS 自动完成 -> Codeigniter:

      barcode = $ this-> input-> get ("term")。 ":*";

      查询: $ query = 'select * from tablaneme where xx @@?限制 15'; $barcodequery = $this->db->query($query,array(explode("",$barcode))))->result_array();

      【讨论】: