2015-04-15 7 views
2

У меня есть posts, у которого есть столбец tags. Я хотел бы иметь возможность выполнять полный текстовый поиск по тегам. Для VARCHAR столбцов я использовал:Postgres Полнотекстовый поиск по Array Column

CREATE INDEX posts_fts_idx ON posts USING gin(to_tsvector('english', coalesce(title, '')); 
SELECT "posts".* FROM "posts" WHERE (to_tsvector('english', coalesce(title, '')) @@ (to_tsquery('english', 'ruby'))); 

Однако для character varying[]to_tsvector функция не существует. Как может быть написан запрос, который будет работать против каждого из тегов (идеально подходящий, если какой-либо один тег совпадает)?

Примечание: я вижу, что это было бы довольно легко сделать преобразование в строку (array_to_string), но если это возможно, я хотел бы преобразовать каждый отдельный тег в tsvector.

ответ

1

Вы можете индексировать символ, изменяющийся с помощью джина для параметров поиска. Попробуйте следующее:

CREATE INDEX idx_post_tag ON posts USING GIN(tags); 

SELECT * FROM posts WHERE tags @> (ARRAY['search string'::character varying]); 

Это то, что требуется точное соответствие. Если точное совпадение нежелательно, вам следует рассмотреть возможность хранения ваших тегов в виде текстового столбца. Подумайте больше о значении этих «тегов». В типах массивов String отсутствует индексация текста, поддержка стебля и перегиба, и, следовательно, вы не сможете сопоставить такие вещи, как «Танцы» с «Танец».

Если это не вариант, вы можете обойти это с неизменной версией функции array_to_string. Ваши запросы будут следующими:

CREATE INDEX posts_fts_idx ON posts USING gin(to_tsvector('english', immutable_array_to_string(tags, ' '))); 
SELECT "posts".* FROM "posts" WHERE (to_tsvector('english', immutable_array_to_string(tags, ' ')) @@ (to_tsquery('english', 'ruby'))); 
+0

Спасибо за ответ, но это не будет использовать полнотекстовый поиск. Это требует точного соответствия и не учитывает орфографические и английские сходства (т. Е. Танцы и танцы). –

+0

Да, я как-то назвал это в своем вопросе - что я пытаюсь применить tsvector к каждому элементу массива - не присоединяться к массиву, а затем применять его. Дело в том, что это будет соответствовать строкам между тегами. –

+0

Для этого вам нужно переместить теги в отдельную таблицу. Я не вижу никакой другой возможности. – TavoloPerUno

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