Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / модель поиска / 11 сообщений из 11, страница 1 из 1
01.07.2008, 12:50
    #35403810
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Прошу совета по модели поиска.
Товар(предположим) характеризуется кодом, названием, описанием и вхождением в группы (у групп тоже есть название).

Поисковая строка может содержать числовые коды товаров (ищем по полному совпадению) и слова (FTS ). Результаты поиска хотелось бы вывести в таком порядке:
- товары, найденные по числовым кодам, отсортированы в порядке перечисления в строке
- товары, найденые по ключевым словам (FTS по нескольким таблицам)

Оставим пока за скобками релевантность результатов для поиска по описанию и вхождению в несколько групп.

рассмотрим такой метод:
- строка поиска разбирается на фрагменты
- фрагменты типизируются на "коды" и "слова"
- первый поиск делаем по ~ "код1" or ~ "код2", сохраняем id найденных во врем. таблицу
- из "слов" формируем tsquery ' слово1 | слово2 ..'
- делаем второй поиск по tsquery @@ tsvector(индексированные поля), тоже сохраняем id во врем. таблице

Скорость отдельного FTS поиска по одной таблице(~50K записей)~10-30 мс.

Но есть подозрение, что для большого числа паттернов в tsquery и объединений по 4-5 таблицам все будет не так радостно.
Как вообще принято решать такие задачи при бОльшем числе таблиц для поиска?
Хранение tsvector для всех искомых полей в отдельной таблице или что-то еще?
...
Рейтинг: 0 / 0
01.07.2008, 13:00
    #35403840
YuriyRusinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Я занимаюсь поиском в базе геоданных, объединяя таблицы с помощью inner join'ов, можно ещё было бы делать через union, intersect и т.п., но сопоставление по скорости поиска было в пользу джойнов.
...
Рейтинг: 0 / 0
01.07.2008, 13:02
    #35403848
YuriyRusinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Само собой разумеется, что критерии поиска уже распатронены.
...
Рейтинг: 0 / 0
01.07.2008, 13:06
    #35403874
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Для меня inner join - не выход. Если, к примеру, какой то товар не входит ни в одну группу, он все равно должен быть найден по своему названию. Т.е. везде вылезают left outer join.
Не забудем и про большое кол-во OR в условии....
...
Рейтинг: 0 / 0
01.07.2008, 13:16
    #35403912
YuriyRusinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
OR ИМХО лучше переделывать в left join, иными словами я сначала в хранимой процедуре формирую запрос, исходя из наличия/отсутствия критериев, а потом его выполняю, и в джойн одна и та же таблица может входить неоднократно под различными алиасами, поэтому товар не входящий в группу можно найти по названию, запихав в джойн таблицу с товарами как-то так
Код: plaintext
select distinct * from (tbl_trades as tbl1 inner join tbl_trades as tbl2 on (<здесь условия поиска>)) 
.
...
Рейтинг: 0 / 0
01.07.2008, 13:27
    #35403958
пуя
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Стоит попробовать всё запихать в один tsvector.
Для смешанных буквенно-цифровых кодов вроде бы все ОК, стемминг их не исковеркает.
Вынесение поиска по коду наверх делается элементарно через ts_rank - нужно лишь при заполнении вектора дать кодам большой вес A, а описаниям - самый маленький D. Названия группы правда не придумаю куда сунуть, наверно всё же отдельно искать.
...
Рейтинг: 0 / 0
01.07.2008, 14:13
    #35404142
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
YuriyRusinov запихав в джойн таблицу с товарами как-то так
Код: plaintext
select distinct * from (tbl_trades as tbl1 inner join tbl_trades as tbl2 on (<здесь условия поиска>)) 
.

Не уверен, что понял.
Положим ключевых слов 10, а таблиц 5. Каждое слово может быть найдено в любой из таблиц.
Что же будет с количеством inner join - 50 штук?
...
Рейтинг: 0 / 0
01.07.2008, 14:13
    #35404148
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
планировщик с таким не справится.
...
Рейтинг: 0 / 0
01.07.2008, 14:17
    #35404159
Oleg Bartunov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
tadminПрошу совета по модели поиска.
Товар(предположим) характеризуется кодом, названием, описанием и вхождением в группы (у групп тоже есть название).

Поисковая строка может содержать числовые коды товаров (ищем по полному совпадению) и слова (FTS ). Результаты поиска хотелось бы вывести в таком порядке:
- товары, найденные по числовым кодам, отсортированы в порядке перечисления в строке
- товары, найденые по ключевым словам (FTS по нескольким таблицам)

Оставим пока за скобками релевантность результатов для поиска по описанию и вхождению в несколько групп.

рассмотрим такой метод:
- строка поиска разбирается на фрагменты
- фрагменты типизируются на "коды" и "слова"
- первый поиск делаем по ~ "код1" or ~ "код2", сохраняем id найденных во врем. таблицу
- из "слов" формируем tsquery ' слово1 | слово2 ..'
- делаем второй поиск по tsquery @@ tsvector(индексированные поля), тоже сохраняем id во врем. таблице

Скорость отдельного FTS поиска по одной таблице(~50K записей)~10-30 мс.

Но есть подозрение, что для большого числа паттернов в tsquery и объединений по 4-5 таблицам все будет не так радостно.
Как вообще принято решать такие задачи при бОльшем числе таблиц для поиска?
Хранение tsvector для всех искомых полей в отдельной таблице или что-то еще?
tsvector позволяет хранить 4 поля (A,B,C,D), которые можно указывать при запросе, например, ищем слово
'лопата' в полях A и C
[src]to_tsquery('лопата:ac') @@ fts/SRC]
Таким образом, один tsvector может обеспечить довольно большое количество разных поисков.
этим же полям в ранжирующей функции можно приписать разный вес.
...
Рейтинг: 0 / 0
01.07.2008, 14:48
    #35404294
YuriyRusinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Слово ищется не в таблице, а в поле таблицы, соотвественно таблицы джойнятся по ключам и добавляются условия типа word1 in (myau-myau-myau) or word2 in (gav-gav-gav) etc. т.е. число left или inner join получится в зависимости только от числа таблиц, в которых осуществляется поиск.
...
Рейтинг: 0 / 0
01.07.2008, 15:12
    #35404384
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
модель поиска
Спасибо, Олег.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create index I_FTS_GIN_Articles_Code on Articles using gin(setweight(to_tsvector('r_ru',Code), 'A'));
create index I_FTS_GIN_Articles_Name on Articles using gin(setweight(to_tsvector('r_ru',Name), 'B'));
create index I_FTS_GIN_Articles_Desc on Articles using gin(setweight(to_tsvector('r_ru',Description), 'C'));

select code,name from articles where  
   to_tsquery('r_ru', ' 1376.066:A | плюшками:B' ) @@@  setweight(to_tsvector('remba_ru', code),'A')
or to_tsquery('r_ru', ' 1376.066:A | плюшками:B' ) @@@ setweight(to_tsvector('remba_ru', name),'B' )
or to_tsquery('r_ru', ' 1376.066:A | плюшками:BC' ) @@@ setweight(to_tsvector('remba_ru', Description),'C' )
делает то, что нужно: видимость для поиска ограничивается.
__
OR используется, потому что при конкатенации tsvector индекс не будет использован.
Для одной таблицы можно сделать составной индекс, но это только пример.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / модель поиска / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]