搜索数据库中(类似)字符串的可扩展方法

Ogn*_*jen 2 postgresql search full-text-search scalability elasticsearch

让我来描述我的问题.有一个输入字符串,以及一个包含数千个字符串的表.我正在寻找最好的方法来搜索输入字符串中最相似的*字符串.搜索应返回~10个建议字符串的列表,按相似度排序.字符串在数据库中也具有与它们相关联的数字权重(流行度),在另一列中,因此如果可能的话,具有较高权重的字符串应该具有更高的出现在结果中的机会.

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

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

输入句子示例:

  • 我不喜欢cangaroos.

来自数据库的示例建议:

  • 袋鼠不是我最喜欢的.
  • 袋鼠是邪恶的.
  • 我曾经有一个cangaroo.再也不.

这些建议应首先出现,因为'cangaroo'在我的数据库中并不常见,因此任何带有'cangaroo'字样的字符串都应该很有可能出现在结果中.检测'不喜欢'可能要困难得多,所以这部分对我来说完全是可选的.

Ps PostgreSQL的全文搜索能做到这样吗?

谢谢.

joa*_*olo 5

PostgreSQL全文搜索无法满足您的需求.但是,PostgreSQL三元组的相似性可以做到.

您首先需要通过在数据库中执行(一次)来安装包含'trigram similarity'和'btree_gist'的包:

CREATE EXTENSION pg_trgm;
CREATE EXTENSION btree_gist;
Run Code Online (Sandbox Code Playgroud)

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

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.') ;
Run Code Online (Sandbox Code Playgroud)

这个表需要一个'trigram索引',以允许PostgreSQL数据库'按相似性索引'.这是通过执行:

CREATE INDEX ON sentences USING GIST (sentence gist_trgm_ops, sentence_id) ;
Run Code Online (Sandbox Code Playgroud)

要找到您正在寻找的答案,请执行:

-- 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 ;
Run Code Online (Sandbox Code Playgroud)

你得到的结果是:

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.
Run Code Online (Sandbox Code Playgroud)

希望这能给你你想要的东西......