powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Полнотекстовый поиск Postgres
25 сообщений из 41, страница 1 из 2
Полнотекстовый поиск Postgres
    #40082346
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!Помогите пожалуйста выбрать верное решение.
Воодные данные таковы
простейшая табличка персона ,в ней 4 текстовых колонки email, и фио
что нужно - пользователь вбивает в форму текст - по нему найти какие записи матчатся
например есть запись Иванов Федр Петрович aaa@a.ru

клиент вводит Федр и получает эту запись
вводит @a.ru
и получает эту запись ,поле для ввода одно ,а не два отедьно под фио и под емайл

Количесво записей около 1 млн .

Не хочется прикручивать сфинкс к проекту ,почитал отзывы - вроде как люди хвалят TS встроеный

У какого какое мнение на этот счет

И хотел спросить вопрос по реализации насколько я понимаю чтобы встроеный механизм работал быстро - нужно хранить векторы в этой же таблице персона или в отдельной 1 к 1 связь и одновляться по тригеру

Может у кого то был опыт - подскажите как правильно это организовать
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082354
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O,

если вам нужен поиск без словоформ (а он тут не нужен судя по всему)
просто используйте pg_trgm и LIKE поиск по триграмному индексу.
На миллионе записей будет нормально работать.
https://www.postgresql.org/docs/13/pgtrgm.html

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082361
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
Ну вообще да ,я думаю что слоформы тут явно лишние,так как email склонять точно не получится
ну а имя фамилия отчество я думаю при поиске и так все вводят в одном падеже и единственном числе
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082363
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk,
Ну вообще да ,я думаю что слоформы тут явно лишние,так как email склонять точно не получится
ну а имя фамилия отчество я думаю при поиске и так все вводят в одном падеже и единственном числе


тогда вам действительно триграммный индекс будет лучше всего.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082371
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O
Maxim Boguk,
Ну вообще да ,я думаю что слоформы тут явно лишние,так как email склонять точно не получится
ну а имя фамилия отчество я думаю при поиске и так все вводят в одном падеже и единственном числе


тогда вам действительно триграммный индекс будет лучше всего.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

только не очень понятно что делать с фио- оно же из трех колонок состоит
как это будет выглядеть в запросе не очень понимаю
придет строка такого плана 'Федор Валентинович' или 'Иван Петров'

или 'Алтуфьев Виктор av@mail.ru'
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082418
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
грубо говоря мне на вход приходит от клиента строка "ДАЙНЕКО ПЕТР ВИКТОРОВИЧ"

как сделать тогда запрос ведь фио состоит из 3 колонок и еще есть емайл не очень понимаю

что то типо такого же должно быть

Код: plsql
1.
select * from person where first_name similar to 'ДАЙНЕКО ПЕТР ВИКТОРОВИЧ' or last_name similar to 'ДАЙНЕКО ПЕТР ВИКТОРОВИЧ' or patronymic similar to 'ДАЙНЕКО ПЕТР ВИКТОРОВИЧ' or email similar to 'ДАЙНЕКО ПЕТР ВИКТОРОВИЧ'
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082438
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O,

А это вам надо определиться вы хотите чтобы при вводе "петр" искало только имя петр или любой вариант вида
петр петрович петроний (фамилиё такое) петр@yandex.ru (email)?

если второе то
индекс можно сделать триграмный по lower(first_name||'|'||last_name||'|'||'patronymic||'|'||email)
и соответственно искать по lower(first_name||'|'||last_name||'|'||'patronymic||'|'||email) like lower('%петр%')

А как оно должно трактовать "ДАЙНЕКО ПЕТР ВИКТОРОВИЧ" - вы про многословне поисковые запросы вообще ничего в исходном посте не говорили.
Скорее всего надо что то вида ... like lower('%ДАЙНЕКО%') and ... like lower('%ПЕТР%) and


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082442
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O,

А это вам надо определиться вы хотите чтобы при вводе "петр" искало только имя петр или любой вариант вида
петр петрович петроний (фамилиё такое) петр@yandex.ru (email)?

если второе то
индекс можно сделать триграмный по lower(first_name||'|'||last_name||'|'||'patronymic||'|'||email)
и соответственно искать по lower(first_name||'|'||last_name||'|'||'patronymic||'|'||email) like lower('%петр%')

А как оно должно трактовать "ДАЙНЕКО ПЕТР ВИКТОРОВИЧ" - вы про многословне поисковые запросы вообще ничего в исходном посте не говорили.
Скорее всего надо что то вида ... like lower('%ДАЙНЕКО%') and ... like lower('%ПЕТР%) and


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

суть в том ,что пользователь может ввести и 'Петр' и "ДАЙНЕКО ПЕТР ВИКТОРОВИЧ" или "ПЕТР ВИКТОРОВИЧ"
а еще "ПЕТР ВИКТОРОВИЧ aaa@a.ru" соотвественно я должен выдвать если 'Петр' то всех петров,если ДАЙНЕКО ПЕТР ВИКТОРОВИЧ
то всех ДАЙНЕКО ПЕТР ВИКТОРОВИЧей,если ПЕТР ВИКТОРОВИЧ" то всех ПЕТР ВИКТОРОВИЧЕЙ, если ПЕТР ВИКТОРОВИЧ aaa@a.ru то всех Петр Викторовичей ,у кого почта aaa@a.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082443
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O,

А это вам надо определиться вы хотите чтобы при вводе "петр" искало только имя петр или любой вариант вида
петр петрович петроний (фамилиё такое) петр@yandex.ru (email)
--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

Хочется чтобы при вводе петр выдавало петров всех,а петровчией и петровых нет
если ввести Петр Петров - тогда всех петр петровых
если Петров то всех Петровых
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082453
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk
O_79_O,

А это вам надо определиться вы хотите чтобы при вводе "петр" искало только имя петр или любой вариант вида
петр петрович петроний (фамилиё такое) петр@yandex.ru (email)
--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

Хочется чтобы при вводе петр выдавало петров всех,а петровчией и петровых нет
если ввести Петр Петров - тогда всех петр петровых
если Петров то всех Петровых


Это уже вам не всякий full text search даст.
Но предполагая что в полях у вас тексты с пробелами не будут в наличии всё ещё можно на триграммах сделать.

Я правильно понимаю что вам фактически то совпадения полей нужны?
Тогда и триграммы то вам не нужны.
Можно обычными совпадениями обойтись и обычными индексами.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082457
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O
пропущено...

Хочется чтобы при вводе петр выдавало петров всех,а петровчией и петровых нет
если ввести Петр Петров - тогда всех петр петровых
если Петров то всех Петровых


Это уже вам не всякий full text search даст.
Но предполагая что в полях у вас тексты с пробелами не будут в наличии всё ещё можно на триграммах сделать.

Я правильно понимаю что вам фактически то совпадения полей нужны?
Тогда и триграммы то вам не нужны.
Можно обычными совпадениями обойтись и обычными индексами.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru


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

Да нужно строгое совпадение - тоесть Петр ввели - значит всех петров отдаем
Пробелов в самой бд не будет ,но клиент понятно будет вводить с пробелами

если это очень сложно - можно попробовать вариант как вы сказали чтобы вы на петр - выдававало и петров и петровичей и петросянов

кстати а втроеный механизм fts постгреса для этого не подойдет?
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082464
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk
пропущено...


Это уже вам не всякий full text search даст.
Но предполагая что в полях у вас тексты с пробелами не будут в наличии всё ещё можно на триграммах сделать.

Я правильно понимаю что вам фактически то совпадения полей нужны?
Тогда и триграммы то вам не нужны.
Можно обычными совпадениями обойтись и обычными индексами.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru


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

Да нужно строгое совпадение - тоесть Петр ввели - значит всех петров отдаем
Пробелов в самой бд не будет ,но клиент понятно будет вводить с пробелами

если это очень сложно - можно попробовать вариант как вы сказали чтобы вы на петр - выдававало и петров и петровичей и петросянов

кстати а втроеный механизм fts постгреса для этого не подойдет?


Ну по полным совпадениям все просто же

WHERE
(first_name='ДАЙНЕКО' or last_name='ДАЙНЕКО' or patronymic='ДАЙНЕКО' or email='ДАЙНЕКО')
AND
(first_name='ПЕТР' or last_name='ПЕТР' or patronymic='ПЕТР' or email='ПЕТР')
AND
...

PS: кстати строго совпадение явно противоречит тому что вы в начале написали
авторвводит @a.ru
и получает эту запись



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082469
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O
пропущено...


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

Да нужно строгое совпадение - тоесть Петр ввели - значит всех петров отдаем
Пробелов в самой бд не будет ,но клиент понятно будет вводить с пробелами

если это очень сложно - можно попробовать вариант как вы сказали чтобы вы на петр - выдававало и петров и петровичей и петросянов

кстати а втроеный механизм fts постгреса для этого не подойдет?


Ну по полным совпадениям все просто же

WHERE
(first_name='ДАЙНЕКО' or last_name='ДАЙНЕКО' or patronymic='ДАЙНЕКО' or email='ДАЙНЕКО')
AND
(first_name='ПЕТР' or last_name='ПЕТР' or patronymic='ПЕТР' or email='ПЕТР')
AND
...

PS: кстати строго совпадение явно противоречит тому что вы в начале написали
авторвводит @a.ru
и получает эту запись



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

понял спасибо за пример,но нужно немного иное
иногда может быть строго соотвествие ,иногда нет

тоесть принцип работы обычного поисковика- если я ввожу петр от выдаст мне петров всех
если я ввожу петр @mail.ru,то я должен получить всех петров у которых домен майл ру
если я ввожу Петрович Петр Петров - то должен получить именно его
тоесть решение должно поддерживать многословность,не важно каков будет порядок ввода - вот такой алгорим поиска нужен.

Я прошу прощения за спутанность некую

я так понимаю что тут нужен именно поисковый движок типо сфинкса ? обычными средставами постгреса не получится такое осуществить?
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082471
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
вообщем не получается у меня по русски норм сформулировать то что надо
вот по английски
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
0


I have a table with text colums last_name,first_name,patronymic,email

Example: we put 1 record to it

'Ivan', 'Vishov', 'Valentinovich', 'aaa@a.com'
Now on client-side we have only one text input. The client can write the following combination to query:

Ivan
Vishov Ivan
Ivan Vishov
Ivan Valentinovich
Ivan aaa@a.ru
In all these cases I want to get the related record.
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082472
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
тоесть по домену искать не надо - если клиент введет @a.ru - то не нужно такое,только почту целиком
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082473
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
похоже таки нужно вот такая конструкция

как вы писали
WHERE
(first_name='ДАЙНЕКО' or last_name='ДАЙНЕКО' or patronymic='ДАЙНЕКО' or email='ДАЙНЕКО')
AND
(first_name='ПЕТР' or last_name='ПЕТР' or patronymic='ПЕТР' or email='ПЕТР')
AND

но насколько быстро она будет работать если на вход прилет Петр Дайнеко Викторович aaa@a.ru
это же 4х4 сравнений
Ведь такое же можно с помощью FTS постгресовской сделать ?
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082477
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk,
похоже таки нужно вот такая конструкция

как вы писали
WHERE
(first_name='ДАЙНЕКО' or last_name='ДАЙНЕКО' or patronymic='ДАЙНЕКО' or email='ДАЙНЕКО')
AND
(first_name='ПЕТР' or last_name='ПЕТР' or patronymic='ПЕТР' or email='ПЕТР')
AND

но насколько быстро она будет работать если на вход прилет Петр Дайнеко Викторович aaa@a.ru
это же 4х4 сравнений
Ведь такое же можно с помощью FTS постгресовской сделать ?


При наличии индексов по всем 4м полям - это всего 16btree index scan и в общем скорее всего оно будет абы не быстрее любго разумного FTS.
Тем более на миллионах (а не миллиардах и более) строк.

На тестовой таблице с 10М строк получается 10-40ms на запрос

Код: sql
1.
2.
3.
4.
5.
6.
create  table qqq as select (random()*1000)::integer as f1, (random()*1000)::integer as f2, (random()*1000)::integer as f3, (random()*1000)::integer as f4 from generate_series(1, 10000000);
create index qqq_f1 on qqq(f1);
create index qqq_f2 on qqq(f2);
create index qqq_f3 on qqq(f3);
сreate index qqq_f4 on qqq(f4);
vacuum ANALYZE qqq;




--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082478
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O
Maxim Boguk,
похоже таки нужно вот такая конструкция

как вы писали
WHERE
(first_name='ДАЙНЕКО' or last_name='ДАЙНЕКО' or patronymic='ДАЙНЕКО' or email='ДАЙНЕКО')
AND
(first_name='ПЕТР' or last_name='ПЕТР' or patronymic='ПЕТР' or email='ПЕТР')
AND

но насколько быстро она будет работать если на вход прилет Петр Дайнеко Викторович aaa@a.ru
это же 4х4 сравнений
Ведь такое же можно с помощью FTS постгресовской сделать ?


При наличии индексов по всем 4м полям - это всего 16btree index scan и в общем скорее всего оно будет абы не быстрее любго разумного FTS.
Тем более на миллионах (а не миллиардах и более) строк.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

я извиняюсь еще раз за вопросы такие,но я так понимаю мне тут нужен обычный индекс ,так как gin gist не работают на строгое соотвествие? и индекс нужен на каждую колонку или же общий индекс на 4 колонки
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082480
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk
пропущено...


При наличии индексов по всем 4м полям - это всего 16btree index scan и в общем скорее всего оно будет абы не быстрее любго разумного FTS.
Тем более на миллионах (а не миллиардах и более) строк.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

я извиняюсь еще раз за вопросы такие,но я так понимаю мне тут нужен обычный индекс ,так как gin gist не работают на строгое соотвествие? и индекс нужен на каждую колонку или же общий индекс на 4 колонки


обычный индекс
на каждую колонку свой
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082481
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,спасибо за помощь)
9 милисекунд на 2 млн записей в таблице

единтсвено что я думаю может все таки Hash index ведь мы будем применять оператор = исключительно?
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082483
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk,спасибо за помощь)
9 милисекунд на 2 млн записей в таблице

единтсвено что я думаю может все таки Hash index ведь мы будем применять оператор = исключительно?


Не надо оно вам... заметного выйгрыша на коротких строках не будет.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082484
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk
O_79_O
Maxim Boguk,спасибо за помощь)
9 милисекунд на 2 млн записей в таблице

единтсвено что я думаю может все таки Hash index ведь мы будем применять оператор = исключительно?


Не надо оно вам... заметного выйгрыша на коротких строках не будет.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

понял ,спасибо
еще вопрос такой хотел задать применимо к данной задаче - насколько быстро бы работал постгресовский FTS тут?
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082485
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
решил немного пощупать FTS постргри
Код: plsql
1.
2.
3.
select * from respondent
where to_tsvector(first_name || ' ' || last_name || ' ' || patronymic || ' '
  || email) @@ to_tsquery('Дайнеко & Петр & Викторович')



[/src]

нужно теперь индексы правильно создать и должно быть неплохо
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082561
O_79_O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk


обычный индекс
на каждую колонку свой

Максим исходя из опыта можете сказать,насколько сильно деградирует производительность при добавлении этих 4 индексов?
например при вставке/удалении особенно пачками
...
Рейтинг: 0 / 0
Полнотекстовый поиск Postgres
    #40082612
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
O_79_O
Maxim Boguk


обычный индекс
на каждую колонку свой

Максим исходя из опыта можете сказать,насколько сильно деградирует производительность при добавлении этих 4 индексов?
например при вставке/удалении особенно пачками


заведомо на меньше чем от добавления FTS GIN индекса который очень тяжелый сам по себе.
а более конкретно ответить на вопрос "насколько сильно" невозможно берите и тестируйте это же вам надо а не мне.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
25 сообщений из 41, страница 1 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Полнотекстовый поиск Postgres
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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