Как правильно реализовать поиск по ключевым фразам?

Добрый день, помогите с вопросом, не могу найти правильный путь..

Есть таблица, в ней поле 'keys' (text[]), в нем хранится список ключевых фраз для поиска, например (абстрактно): {"прическа мужская", "прически 2016", "мужская парикмахерская"} и пр.

Нужно, что бы поиск происходил не зависимо от контекста запроса, например можно было найти эту запись по примерно таким запросам: "актуальные мужские прически", "найти парикмахерскую для мужчин" и прочее.

P.S.
сейчас стараюсь придти к решению на этот вопрос так:
ispell-словари для PostgreSQL и полнотекстовый поиск, но не совсем понимаю как сделать одновременно и поиск по массиву..

Спасибо за внимание.
  • Вопрос задан
  • 347 просмотров
Решения вопроса 2
al_gon
@al_gon
Правильно было бы отказаться от SQL и идти в сторону поисковых движков.
Ответ написан
sergey-gornostaev
@sergey-gornostaev Куратор тега PostgreSQL
Седой и строгий
Запугали человека. Может у него база мааааленькая и ненагруженная. В этом случае можно и постгрессовским FTS'ом обойтись.

Перед поиском массив нужно просто конвертировать в строку.
SELECT id FROM some_table WHERE to_tsquery('причёска') @@ to_tsvector(array_to_string(keys, ', '));

Однажды таблица вырастит и захочется ускорить поиск индексом. Самый просто способ - создать функциональный индекс, который будет поле keys конвертировать в строку.
CREATE INDEX keys_fts_idx ON some_table USING gin(to_tsvector(array_to_string(keys, ', ')));

А когда захочется ещё ускориться, можно использовать вариант, который наиболее часто применяется - добавить в таблицу ещё одно поле и сделать триггер, который при вставке или обновлении записи будет поле keys этой записи конвертировать в строку и в дополнительное поле сохранять, а индекс для полнотекстового поиска строить уже по этому полю.
ALTER TABLE some_table ADD COLUMN keys_fts tsvector;
CREATE INDEX keys_fts_idx ON some_table USING gin(keys_fts);

CREATE FUNCTION keys_fts_update() RETURNS TRIGGER AS $$
BEGIN
	IF (TG_OP = 'UPDATE') THEN
		IF OLD.keys <> NEW.keys THEN
			NEW.keys_fts = to_tsvector(array_to_string(NEW.keys, ', '));
			RETURN NEW;
		ELSE
			RETURN NEW;
		END IF;
	ELSIF (TG_OP = 'INSERT') THEN
		NEW.keys_fts = to_tsvector(array_to_string(NEW.keys, ', '));
		RETURN NEW;
	END IF;
	RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';

CREATE TRIGGER keys_fts_update BEFORE INSERT OR UPDATE ON some_table
FOR EACH ROW EXECUTE PROCEDURE keys_fts_update();
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы