ts_rank между двумя столбцами ts vector - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть два столбца в двух таблицах, и я хочу выбрать 20% верхних наиболее релевантных терминов

Table A: items
id, 
title (string)

Table B: queries
id,
query (string)

По сути, я хочу найти 20% верхнего ранга сравнения для ts_vector (items. title) и ts_vector (query.query)

1 Ответ

2 голосов
/ 09 ноября 2019

Вы можете использовать ts_rank_cd(tsquery, tsvector, int) для получения близости текста. Я создал две таблицы a и b с вашими столбцами и поместил информацию об этом. Функция ts_rank_cd получает коэффициент для нормализации, в документации 32 - это значение для нормализации между 0 и 1. Он не считается индексом от 0% до 100%, но считается хорошим фактором близости, как объяснено в элементах управления текстовым поиском .

Таблица a:

postgres=# select * from a;
 id |       title        
----+--------------------
  1 | a rat and a cat
  2 | a cat and a mouse
  3 | a tiger or a rhino
(3 rows)

Таблица b:

postgres=# select * from b;
 id |      query      
----+-----------------
  4 | lorem ipsum
  3 | lorem cat
  2 | mouse rhino
  1 | a rat and a cat
  5 | rat fat cat
(5 rows)

Сравнение должно быть выполнено с ts_rank_cd(tsvector, tsquery), поэтому мы конвертируем первые a.title в tsvector и b.query в tsquery и проводим сравнение.

postgres=# select ts_rank_cd(to_tsvector(title), query, 32) as rank, 
                  title,
                  query 
             from a, 
                  (select plainto_tsquery('english', query) as query,
                          id
                     from b
                  ) AS b ORDER BY rank DESC; 

   rank    |       title        |         query         
-----------+--------------------+-----------------------
 0.0322581 | a rat and a cat    | 'rat' & 'cat'
         0 | a rat and a cat    | 'lorem' & 'cat'
         0 | a rat and a cat    | 'mous' & 'rhino'
         0 | a rat and a cat    | 'rat' & 'fat' & 'cat'
         0 | a cat and a mouse  | 'lorem' & 'ipsum'
         0 | a cat and a mouse  | 'lorem' & 'cat'
         0 | a cat and a mouse  | 'mous' & 'rhino'
         0 | a cat and a mouse  | 'rat' & 'cat'
         0 | a cat and a mouse  | 'rat' & 'fat' & 'cat'
         0 | a tiger or a rhino | 'lorem' & 'ipsum'
         0 | a tiger or a rhino | 'lorem' & 'cat'
         0 | a tiger or a rhino | 'mous' & 'rhino'
         0 | a tiger or a rhino | 'rat' & 'cat'
         0 | a rat and a cat    | 'lorem' & 'ipsum'
         0 | a tiger or a rhino | 'rat' & 'fat' & 'cat'
(15 rows)

Если вы хотите получить более «расслабленный» результат, вы можете заменить & на |, просто сделав замену.

postgres=# select ts_rank_cd(to_tsvector(title), replace(query::text, '&', '|')::tsquery, 32) as rank, 
                 title::tsvector,
                 replace(query::text, '&', '|')::tsquery from a, (select 
                 plainto_tsquery('english', query) as query, id from b) AS  b ORDER BY rank DESC; 
   rank    |          title           |        replace        
-----------+--------------------------+-----------------------
  0.166667 | 'a' 'and' 'cat' 'rat'    | 'rat' | 'cat'
  0.166667 | 'a' 'and' 'cat' 'rat'    | 'rat' | 'fat' | 'cat'
 0.0909091 | 'a' 'or' 'rhino' 'tiger' | 'mous' | 'rhino'
 0.0909091 | 'a' 'and' 'cat' 'rat'    | 'lorem' | 'cat'
 0.0909091 | 'a' 'and' 'cat' 'mouse'  | 'lorem' | 'cat'
 0.0909091 | 'a' 'and' 'cat' 'mouse'  | 'rat' | 'cat'
 0.0909091 | 'a' 'and' 'cat' 'mouse'  | 'mous' | 'rhino'
 0.0909091 | 'a' 'and' 'cat' 'mouse'  | 'rat' | 'fat' | 'cat'
         0 | 'a' 'or' 'rhino' 'tiger' | 'rat' | 'fat' | 'cat'
         0 | 'a' 'and' 'cat' 'rat'    | 'mous' | 'rhino'
         0 | 'a' 'and' 'cat' 'mouse'  | 'lorem' | 'ipsum'
         0 | 'a' 'or' 'rhino' 'tiger' | 'lorem' | 'ipsum'
         0 | 'a' 'or' 'rhino' 'tiger' | 'lorem' | 'cat'
         0 | 'a' 'or' 'rhino' 'tiger' | 'rat' | 'cat'
         0 | 'a' 'and' 'cat' 'rat'    | 'lorem' | 'ipsum'
(15 rows)
...