1

Позвольте мне описать мою проблему. Существует строка ввода и таблица, содержащая много тысяч строк. Я ищу лучший способ поиска наиболее похожих строк * во входную строку. Поиск должен вернуть список из ~ 10 предложенных строк, отсортированных по степени сходства. Строки также имеют числовые веса (популярность), связанные с ними в базе данных, в другой колонке, поэтому те, у которых более высокий вес, должны иметь более высокую вероятность появления в результатах, если это возможно.Масштабируемый способ поиска (похожих) строк в базе данных

Для чего это лучшая библиотека? Думаю, я ищу что-то похожее на Elasticsearch. У меня нет большого опыта работы с этими библиотеками, поэтому мне нужно было бы легко включить в мой проект и, желательно, с открытым исходным кодом. Я использую Python (Flask и SQLAlchemy) и Postgresql, но также могу использовать, например. Node.js, если необходимо.

* Я также хочу уточнить, какое сходство я ищу. В идеале это было бы семантическое сходство, но лексическое сходство тоже прекрасное. Я был бы доволен всем, что работает хорошо, легко реализовать и максимально масштабируемо и качественно.

Пример входных данных предложение:

  • мне не нравится cangaroos.

Пример предложения из базы данных:

  • Cangaroos не мой любимый.
  • Кангаро являются злыми.
  • У меня когда-то был кангаро. Больше никогда.

Эти предложения должны появиться в первую очередь потому, что «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.') ; 

Эта таблица нуждается в «индексе триграмм», чтобы база данных 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

 Смежные вопросы

  • Нет связанных вопросов^_^