как сделать 'any (:: text []) ilike :: text' - PullRequest
2 голосов
/ 21 марта 2011

здесь структура таблицы

table1
pk int, email character varying(100)[]

data
1, {'mr_a@gmail.com', 'mr_b@yahoo.com', 'mr_c@postgre.com'}

что я пытаюсь достичь, это найти любой «gmail» из записи

query
select * from table1 where any(email) ilike '%gmail%';

, но any () может быть только слева, а unnest () может снизить производительность. У кого-нибудь есть идеи?

редактировать

На самом деле, я немного запутался, когда впервые пишу. я пытаюсь достичь с помощью any (array []) .

это моя фактическая структура

pk int, 
code1 character varying(100), 
code2 character varying(100), 
code3 character varying(100), ...

мой первый подход

select * from tabl1 where code1 ilike '%code%' or code2 ilike '%code%' or...

тогда я попробую

select * from table1 where any(array[code1, code2, ...]) ilike '%code%'

который не работает.

Ответы [ 2 ]

5 голосов
/ 26 марта 2011

Создайте оператор, который реализует ILIKE «в обратном направлении», например:

CREATE FUNCTION backward_texticlike(text, text) RETURNS booleans
    STRICT IMMUTABLE LANGUAGE SQL
    AS $$ SELECT texticlike($2, $1) $$;

CREATE OPERATOR !!!~~* (
    PROCEDURE = backward_texticlike,
    LEFTARG = text,
    RIGHTARG = text,
    COMMUTATOR = ~~*
);

(обратите внимание, что ILIKE внутренне соответствует оператору ~~*. Выберите свое собственное имя для обратного.)

Тогда вы можете запустить

SELECT * FROM table1 WHERE '%code%' !!!~~* ANY(ARRAY[code1, code2, ...]);
2 голосов
/ 21 марта 2011

Хранение адресов электронной почты в нормализованной структуре таблиц.Тогда вы сможете избежать затрат на unnest, иметь «правильный» дизайн базы данных и в полной мере использовать индексирование.Если вы хотите выполнять полнотекстовые запросы, вам следует сохранить адреса электронной почты в таблице, а затем использовать тип данных tsvector , чтобы вы могли выполнять полнотекстовые запросы И использовать индексы.ILIKE '%whatever%' приведет к полному сканированию таблицы, так как планировщик не может использовать любой запрос.С вашим текущим дизайном и достаточным количеством записей, unnest будет меньше всего ваших забот.

Обновление Даже с учетом обновлений вопроса использование таблицы нормализованных кодов вызовет у вас наименьшее количество головной боли и приведет к оптимальному сканированию.Каждый раз, когда вы создаете пронумерованные столбцы, это хороший признак того, что вы можете захотеть нормализовать.При этом вы можете создать вычисляемый текстовый столбец для использования в качестве столбца поисковых слов.В вашем случае вы можете создать столбец search_words, который заполняется при вставке и обновляется триггером.Затем вы можете создать tsvector для построения полнотекстовых запросов на search_words

...