Postgres Текстовый поиск с дополнительными словами / токенами - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть таблица с английскими предложениями sh. Учитывая предложение, которое может содержать дополнительное слово или искаженное слово, могу ли я найти ближайшее предложение в таблице, используя Postgres 'Возможности текстового поиска?

to_tsvector('a b c') @@ plainto_tsquery('a b'), возвращает true

to_tsvector('a b') @@ plainto_tsquery('a b c') возвращает ложь

Мне бы хотелось, чтобы сценарий 2 также возвращал истину.

Примечания:

  1. Длина предложений может составлять десятки слов , Я ищу эффективное решение ..
  2. Другие системы текстового поиска, такие как Elastic / Solr, успешно вернут самый близкий результат.

Дополнительная информация о снижении производительности индекс триграммы.

EXPLAIN (ANALYSE, BUFFERS)
SELECT
    similarity(title, 'electode paste composition') as sml,
    title
FROM
    table
WHERE
    title % 'electode paste composition'
ORDER BY
    sml DESC;

возвращает:

Gather Merge  (cost=1880112.22..1902381.94 rows=190870 width=93) (actual time=36355.303..36356.143 rows=5 loops=1)
  Workers Planned: 2
  Workers Launched: 2
  Buffers: shared hit=407649
  ->  Sort  (cost=1879112.20..1879350.78 rows=95435 width=93) (actual time=36344.180..36344.180 rows=2 loops=3)
        Sort Key: (similarity(title, 'electode paste composition'::text)) DESC"
        Sort Method: quicksort  Memory: 25kB
        Worker 0:  Sort Method: quicksort  Memory: 25kB
        Worker 1:  Sort Method: quicksort  Memory: 25kB
        Buffers: shared hit=407649
        ->  Parallel Bitmap Heap Scan on table  (cost=2759.10..1866325.66 rows=95435 width=93) (actual time=35940.284..36344.141 rows=2 loops=3)
              Recheck Cond: (title % 'electode paste composition'::text)"
              Rows Removed by Index Recheck: 14904
              Heap Blocks: exact=16199
              Buffers: shared hit=407635
              ->  Bitmap Index Scan on title_trgm  (cost=0.00..2701.84 rows=229045 width=0) (actual time=35543.907..35543.907 rows=44716 loops=1)
                    Index Cond: (title % 'electode paste composition'::text)"
                    Buffers: shared hit=362988
Planning Time: 0.084 ms
Execution Time: 36356.187 ms

Тот же запрос, использующий запрос, занимает менее 2,5 секунд.

1 Ответ

1 голос
/ 11 февраля 2020

Если предположить, что ваши слова длиннее одного символа, я бы порекомендовал индексы триграмм:

CREATE EXTENSION pg_trgm;

CREATE INDEX ON atable USING gin (textcol gin_trgm_ops);

SELECT * FROM atable WHERE textcol % 'search string';

% - оператор подобия.

...