1

让我来描述我的问题。有一个输入字符串和一个包含数千个字符串的表。我正在寻找最好的方式来搜索输入字符串最相似的*字符串。搜索应返回约10个建议字符串的列表,按相似度排序。如果可能的话,字符串在数据库中也有与其相关的数字权重(受欢迎度),因此权重更高的字词在结果中应该有更高的出现机会。在数据库中搜索(类似)字符串的可扩展方式

什么是最好的图书馆来实现这一目标?我在寻找类似于Elasticsearch的东西。我对这些类型的库没有太多经验,所以我需要一些容易包含在我的项目中的东西,最好是开源的。我使用Python(Flask和SQLAlchemy)和Postgresql,但也可以使用例如Node.js,如果需要的话。

*我也想澄清一下我在寻找什么样的相似性。理想情况下,它会是语义相似性,但词汇相似性也很好。我会很满意任何可以正常工作的,易于实现的,并且尽可能具有可扩展性和高性能的工具。

例输入句子:

  • 我不喜欢cangaroos。从数据库

例建议:

  • Cangaroos不是我喜欢的。
  • Cangaroos是邪恶的。
  • 我曾经有一个cangaroo。再也不。

这些建议应该首先出现,因为'cangaroo'在我的数据库中不是一个常用单词,所以任何带有'cangaroo'单词的字符串都应该在结果中出现。可能难以发现“不喜欢”,因此这部分对我来说是完全可选的。

P.s. PostgreSQL的全文搜索能做到这样吗?

谢谢。

回答

3

PostgreSQL的全文搜索不能做你要找的东西。然而,PostgreSQL trigram similarity可以做到这一点。

需要先通过执行(一次)在数据库中安装有“卦相似”和“btree_gist”,包装:

CREATE EXTENSION pg_trgm; 
CREATE EXTENSION btree_gist; 

我假设你有一个表,看起来像这样的:

CREATE TABLE sentences 
(
    sentence_id integer PRIMARY KEY, 
    sentence text 
) ; 

INSERT INTO sentences (sentence_id, sentence) 
VALUES 
    (1, 'Cangaroos are not my favorite.'), 
    (2, 'A vegetable sentence.'), 
    (3, 'Cangaroos are evil.'), 
    (4, 'Again, some plants in my garden.'), 
    (5, 'I once had a cangaroo. Never again.') ; 

该表需要'trigram索引'来允许PostgreSQL数据库'按相似性索引'。这是通过执行来实现:

要找到你要找的答案,你执行:

-- Set the minimum similarity you want to be able to search 
SELECT set_limit(0.2) ; 

-- And now, select the sentences 'similar' to the input one 
SELECT 
    similarity(sentence, 'I don''t like cangaroos') AS similarity, 
    sentence_id, 
    sentence 
FROM 
    sentences 
WHERE 
    /* That's how you choose your sentences: 
     % means 'similar to', in the trigram sense */ 
    sentence % 'I don''t like cangaroos' 
ORDER BY 
    similarity DESC ; 

,你得到的是结果:

similarity | sentence_id | sentence 
-----------+-------------+------------------------------------- 
    0.3125 |   3 | Cangaroos are evil.  
    0.2325 |   1 | Cangaroos are not my favorite. 
    0.2173 |   5 | I once had a cangaroo. Never again. 

希望这给你想要什么...

+0

谢谢Joanolo,它工作完美! – Ognjen

+0

如果有人需要在Flask-SQLAlchemy中执行此操作,请告诉我,我将发布我的代码。 – Ognjen