освоен новый фокус: Полнотекстовый поиск в postgresql по части слова. фактически как Like но порядок слов может быть любой.
классический полнотекстовый поиск записывается так
SELECT * FROM table1 WHERE to_tsvector('russian',name_column) @@ plainto_tsquery('russian','красное курткой')
plainto_tsquery('russian',:searchtext) уберет из :searchtext все предлоги, местоимения, спецсимволы, окончания и превратит в выражение вида 'word1' & 'word2'.....& 'wordn'. т.е. выражение 'красное курткой' станет 'красн' & 'куртк'
to_tsvector('russian',name_column) приведет некий текст к списку слово без окончания - места где встретились.
т.е. 'красное курткой совсем красный' станет чем-то вроде 'красн':1,4 'куртк':2 'совсем':3
и далее поиск идет по совпадающим словам.
т.е. результатом запроса
SELECT
to_tsvector('russian','красное мороженным') ,
plainto_tsquery('russian','краса'),
to_tsvector('russian','красное мороженным') @@ plainto_tsquery('russian','краса')
даст строку вида
'красн':1 'морожен':2 | 'крас'| false
но вот мало где написано что если в tsquery записать 'word1':* то результат поиска по ts_vector будет похож на результат поиска по выражению like '% word1% %'
SELECT
to_tsvector('russian','красное мороженным') ,
to_tsquery('russian','краса:*'),
to_tsvector('russian','красное мороженным') @@ to_tsquery('russian','краса:*')
'красн':1 'морожен':2 | 'крас:*'| true
т.е. остается привести выражение 'word1' & 'word2'.....& 'wordn' к виду 'word1':* & 'word2':*.....& 'wordn':* и поиск будет выглядеть как like но с любым порядком слов. И тут я не придумал ничего лучше чем слишком сильно навороченное выражение вида
cast(replace(cast(plainto_tsquery('russian',:search) as text),' & ',':*&') || ':*' as tsquery)
update
вылезла неприятность если запрос не содержит букв алфавита то plainto_tsquery возвращает "". а выражение "'':*" является недопустимым
обход
case when
plainto_tsquery('russian',:search) !=''
then
cast(replace(cast(plainto_tsquery('russian',:search) as text),' & ',':*&') || ':*' as tsquery)
else
true
end