elasticsearch,full-text-search,scalability,Postgresql,Search,elasticsearch,Full Text Search,Scalability" /> elasticsearch,full-text-search,scalability,Postgresql,Search,elasticsearch,Full Text Search,Scalability" />

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

Postgresql 在数据库中搜索(类似)字符串的可扩展方式,postgresql,search,elasticsearch,full-text-search,scalability,Postgresql,Search,elasticsearch,Full Text Search,Scalability,让我描述一下我的问题。有一个输入字符串和一个包含数千个字符串的表。我正在寻找搜索与输入字符串最相似的*字符串的最佳方法。搜索应返回约10个建议字符串的列表,按相似度排序。字符串在数据库的另一列中也有与之相关联的数字权重(流行度),所以如果可能的话,权重越高的字符串出现在结果中的几率越高 实现这一目标的最佳库是什么?我想我正在寻找类似Elasticsearch的东西。我对这类库没有太多的经验,所以我需要一些容易包含在我的项目中的东西,最好是开源的。我正在使用Python(Flask和SQLAlch

让我描述一下我的问题。有一个输入字符串和一个包含数千个字符串的表。我正在寻找搜索与输入字符串最相似的*字符串的最佳方法。搜索应返回约10个建议字符串的列表,按相似度排序。字符串在数据库的另一列中也有与之相关联的数字权重(流行度),所以如果可能的话,权重越高的字符串出现在结果中的几率越高

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

*我还想澄清我在寻找什么样的相似性。理想情况下,应该是语义相似,但词汇相似也可以。我会很高兴任何工作正常,易于实施,并尽可能可扩展和性能

输入句子示例:

  • 我不喜欢cangaroos
来自数据库的建议示例:

CREATE EXTENSION pg_trgm;
CREATE EXTENSION btree_gist;
  • 卡加罗不是我的最爱
  • 卡加罗人是邪恶的
  • 我曾经有过一个坎加罗。再也不会了
这些建议应该首先出现,因为“cangaroo”在我的数据库中不是一个常见的词,所以任何带有“cangaroo”的字符串都有很大的机会出现在结果中。检测“不喜欢”可能要困难得多,所以那个部分对我来说是完全可选的

另外,PostgreSQL的全文搜索可以做这样的事情吗


谢谢。

PostgreSQL全文搜索无法满足您的要求。然而,我能做到

您首先需要通过在数据库中执行(一次)来安装具有“trigram相似度”和“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数据库“按相似性索引”。这是通过执行以下命令来实现的:

CREATE INDEX ON sentences USING GIST (sentence gist_trgm_ops, sentence_id) ;
要找到您正在寻找的答案,请执行以下操作:

-- 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.

希望这能满足您的需要…

如果有人需要在Flask SQLAlchemy中执行此操作,请告诉我,我将发布我的代码。@Ognjen请在我执行相同操作时共享Flask python代码。提前谢谢!