Задать вопрос
Ответы пользователя по тегу PostgreSQL
  • Как найти частичные совпадения строки запроса в БД для полнотекстового поиска PostgreSQL?

    ayazer
    @ayazer
    Sr. Software Engineer
    Т.е. сделать свой препарсер, который будет отдавать потом запрос в нормальный парсер, который обрежет словоформы.


    на моем опыте - любое использование полнотекстового поиска (будь это еластик, солр или встроенный в постгрес) именно этим и заканчивалось. Рано или поздно все-равно возникает необходимость сделать что-то большее чем "взять запрос от пользователя и передать дальше". Начиная от банального "выделить ключевые слова чтоб они в результатах поиска имели больший вес", "этот пользователь не может видеть некоторых результатов" или "затереть все что похоже на пароль" и заканчивая "тут на самом деле поиск по частично структуированым данным, потому для части запросов мы можем вообще другой скл генерировать"

    Дальше это нужно ранжировать. У нас OR, и я не очень понимаю, как будут распределяться веса

    если тут нужно МНОГО специфических настроек - лучше сразу смотреть в сторону того-же солра. В постгресе все-же поддержка полнотекстового поиска постолько-поскольку. Для многих задач ее хватает, но я в свое время страдал т.к. постоянно натыкался на стену "а так сделать нельзя". Но в целом хоть как-то постгрес ранжирует +есть возможность ручками подправить веса для ключевых частей. Т.е. для примера

    select json_flat_content , ts_rank_cd(json_flat_tsv, 'jzvmw | julva | qxqvh | name | value') r
    from my_fulltext_index i
    where
    	i.json_flat_tsv @@ to_tsquery('simple', 'jzvmw | julva | qxqvh | name | value')
    order by r desc


    вернет

    [{"name": "qtmlx", "value": "jzvmw  vajwq julva  ipsmwtbhki  lhgzr"}, {"name": "fslto", "value": "viykw"}]	0.6
    [{"name": "lhnhq", "value": "sxgxh!!daxrh guxux!!kfgtirmgig!!ivqwz"}, {"name": "qxqvh", "value": "qbeli"}]	0.5
    [{"name": "cepja", "value": "mrfma"}, {"name": "gwjqa", "value": "csxaf"}]	0.4
    [{"name": "val", "value": "TNhmT<KxERm"}]	0.2


    ну и да, для запроса "мультфильм | Норштейн | Ежик <-> тумане" может понадобится ручками указать меньший вес для "мультфильм" и больший для "Норштейн". И заодно подумать что делать если в поиске из-за очепятки будет "орНштейн"

    + стоит обратить внимание что постгрес (по крайней мере версии 9.5 и 10.? с которыми я работал) плохо работал с нграмами. а точнее - для этого нужно было ставить доп. плагины и потом все это собирать в кучу. т.е. по"сло:*" найти "слово" можно, но по "ово" найти "слово" - уже нет.

    + возможно нужна будет работа с очепятками

    + я не помню умеет ли постгрес работать с синонимами. Это может быть тоже важно

    в целом как для быстрого и сердитого прототипирования - полнотекстовый поиск в постгресе удобно использовать. Но если нужен серьезный полнотекстовый поиск - лучше смотреть на инструменты которые на это заточены
    Ответ написан
    1 комментарий
  • Из-за чего ошибка nodejs client password must be a string?

    ayazer
    @ayazer
    Sr. Software Engineer
    const pool = new Pool({
      user:'postgres',
      password:'password',
      host:'localhost',
      port:5432,
      database:'delviery'
    });


    pasword => password
    Ответ написан
    Комментировать
  • Как организовать поиск по названиям продуктов, по части названия?

    ayazer
    @ayazer
    Sr. Software Engineer
    в принципе вариантов несколько тут: solr (который использует lucene), elastic (который использует lucene), lucene (и самому дописать весь функционал который добавляет elastic\solr) и внутренний полнотекстовый поиск в постгреса (когда нужен полнотекстовый поиск, но не настолько чтоб ради него поднимать solr/elastic).

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

    поиск по части слова не работает. то есть введя "греч" - сейчас не находит ничего, так как организован полнотекстовый поиск, а хотелось бы чтобы выдавались результаты с учётом следующих пунктов.

    перепроверьте как вы запрос составляете. для solr я бы ожидал увидеть поиск по "греч*", для постгреса - поиск по "греч:*"

    необходим поиск вместе с синонимами, то есть введя "гречка", искало бы и "гречневый", "греча" итд с учётом словоформ. Есть, например, "хлебцы с гречей".

    словари с синонимами настраиваются везде

    проблема с ранжированием: хотелось, чтобы если искомое слово(или словоформа) ближе к началу строки(название продукта), то такой результат выше в поиске. Сейчас выходит как-то вперемешку: например, поиск по слову "гречневая"

    ну это то, как работает обратный индекс. он ничего не знает про позицию слова, он знает только про факт вхождения слова в результат. в постгресе например я не вижу универсального решения как можно получить такое поведение. Перечитайте документацию про ранжированию/весам, я не удивлюсь если в солр/еластике что-то дописали

    UPD: ну и таки да, в комментариях подсказывают что это решается и гуглить документацию по "TF-IDF"
    Ответ написан
  • Перенос таблиц из одной бд в другую в postgresql?

    ayazer
    @ayazer
    Sr. Software Engineer
    итак, вопрос на самом деле можно привести к "как построить процесс внесения изменений в базу, чтоб все случайно не угробить и не было больно".

    1. можно использовать тулзы для генерации дифоф а-ля https://github.com/djrobstep/migra

    дифы добавляются вместе с пр, если схема была изменена пока работаешь - накатываешь диффы у себя локально, генерируешь новый дифф и добавляешь его в пр.

    2. чтоб автоматизировать накатывание дифов на базу - можно использовать flyway (или любой другой аналог). суть проста - оно ведет историю выполненых миграций, при запуске приложение - применяет все новые в правильном порядке

    3. в момент когда данных становится много - оно теряет актуальность т.к. на практике все миграции все-равно выполняется ручками (т.е. не запустил-и-забыл). (дальше мой опыт касается больше майскля, т.к. в постгресе у нас нет многотерабайтных таблиц) основная проблема тут - изменения таблицы = лок = аутейдж, чего допускать нельзя. потому для того, чтоб внести изменения - надо создать новую таблицу с новой схемой, перелить в нее все старые данные, синхронизировать все новые данные, поменять таблицы местами и дропнуть старую. тут помогает тулкит перконы и гитхаба (pt-online-schema-change и gh-ost), которые это все автоматизируют. Но обе они заточены под майскл, для постгреса надо искать и тестировать (ну или может кто-то уточнит)
    Ответ написан
    Комментировать
  • Как лучше организовать заполнение таблиц БД дефолтными данными при деплое?

    ayazer
    @ayazer
    Sr. Software Engineer
    эти данные - часть миграции базы, и соотв. лежать должны где-то там. Если используется орм - у них обычно есть механизмы для выполнения миграций. Если орм не используется и/или хочется больше контроля - Flyway или аналоги. если система глубоко в продакшене и для внесения изменений нужны многоэтапные миграции длиной в недели/месяцы - хоть папка sql_migrations где-то в корне репозитория
    Ответ написан
    Комментировать