Лучшие технологии для поиска в базе данных через regex?
У меня есть база данных из миллиона документов с текстом, в которых дана информация о судебных решениях. В них даны имена, типы судебных исков и тд.
Мне нужно создать веб сервис, в котором пользователь сможет искать по базе данных по заданным таким данным/параметрам из этих судебных решений, то есть идет чистая работа с текстом (я так понимаю надо взять sphinx или ElasticSearch). Но мне нужно не просто поиск фразы по тексту, а делать сложный поиск типа regex.
Например, пользователь на сайте будет писать в поле "Найти судью:" судью "Иванова".
Тогда поиск будет типа "/Судья на заседании: (.*?)/s", где $1 = "Иванова".
Вопрос:
1) в какой базе данных (postgresql, mongodb, redis и тд..) лучше мне это хранить в вебе и на каком языке создать такой сервис (php, ruby, python и тд..), чтобы быстро все работало при большой выборке? Какими методами и технологиями можно сделать такой поиск по миллиону документов?
2) если невозможно сделать такой regexp поиск, будет ли быстро работать поиск, если искать 1 млн. сразу, а потом к каждому документу выдачи уже не на sql, а на backend'e применять фильтр на regexp (то есть отображать этот документ по Ивановой судьи или нет)?
1) никакой, это всё равно full scan не самым дешёвым конечным автоматом.
2) нет, не будет
Быстро будет работать, если вы предварительно распарсите и нормализуете индекс документов.
Надо искать судью? Распарсите свои документы, получите список связей, в каких документах какие судьи участвуют. И так с остальными данными, по которым надо искать.
Спасибо за ответ. А что тогда делать, если я запарсю индексы предварительно, а потом спустя время мне нужно будет добавить еще один параметр для поиска? Тогда придется заново всю бд парсить, что неудобно?
Да, придётся парсить эти данные по всему массиву документов. Перебрать лям документов раз в год по требованию - это принципиально не то же самое, что перебирать лям документов в рантайме.
Это самая малая из предстоящий проблем, чистое машинное время, да и то не слишком большое. Миллион документов не так и много. Хотя, конечно, в зависимости от документов и как вы их разбор реализуете.
По граблям "в этих документах 'Судья на заседании', в тех - 'Судья'" или "здесь Иванова А.А., там А.А. Иванова, а сям - полностью ФИО" и ещё каких-нибудь вариациях пока не ходили, что ли? Якобы типовые документы нормализовать до на самом деле стандартной формы бывает не просто. А то ещё выходит распоряжение, и до такой-то даты по одной форме пишется, потом по другой, потом по третей. Тут имея вагон времени разобрать трудоёмко, а вы в рантайме хотите.
А нормализовать индексы документов, имеется ввиду в базе данных создать еще один столбец "Судья", куда я запишу судью данного документа при добавлении его в бд, а потом делать поиск судей именно по этому столбцу? Это имеете ввиду?
Что-то вроде этого.
Можно порезать на json документы и пихать их в какой-нибудь mongodb или ещё что-нибудь документо-ориентированное. Или в jsonb postgresql.
Можно нормализовать в реляционную базу. Получится более строгая схема.
Не знаком с вашей предметной областью, но разве в суде судья всегда только 1? Коллегиальные суды не рассматриваете?
Я так думаю, что как раз ES здесь очень даже к месту. Тем более, что поиск будет осуществляться по термам слов, и можно будет искать не только "Судья на заседании: Иванова", но и "Судьи в председательстве Ивановой", "судью Иванову" и прочее.
Попробуйте, ES имеет особенности, но не так уж и страшен.
PS. Уж как минимум, ES позволит сократить список рассматриваемых документов до разумного минимума, по которому можно и программный regexp сделать.
Т.е. сначала выбираем из ES все доки с судьями, заседаниями и Ивановой, а уже по результатам поиска делаем фильтрацию своим программным регекспом.
Ах, да, совсем забыл - есть еще скрипты, которые могут как раз это и сделать на стороне самого ES! Ну и люсиновский поиск поддерживает "точный поиск" фраз, если чо..
Берите Elastic. Там есть нечеткий поиск( Иавнов вместо Иванов), фасетный поиск(поиск по аттрибутам документа например фамилия судьи), поиск по регуляркам(т.е. вам не нужно будет обрабатывать результат поиска - нужно будет в поисковый запрос дописать то что вы хотели делать регуляркой самостоятельно), поиск по синонимам(в поисковой строке написали автомобиль а в тексте написано машина) и т.д и т.п.
Технология поиска, которую вы описываете называется полнотекстовый поиск. На миллионах документов работает быстро - именно её реализовывают elastic, sphinx и похожие программы. Эти программы используются на многих сайтах для поиска по большим объёмам имеющихся данных- на том же stackoverflow, instagram и т.п.
Бд можно взять postgres, т.к. там хорошо работает шардинг и репликация.
Язык можно взять тот который вы лучше знаете. Главное сервер брать помощнее, т.к. основную работу будет делать поисковая система. Говорят что новый php 7 кушает в два раза меньше оперативной памяти чем раньше, но на мой взгляд php фреймворки очень сильно уступают тому же python Django в плане удобства использования и долгосрочной поддержки уже написанного кода.
Быть может вам стоит сначала перевести все эти файлы в БД и уже с ней работать. Т.е сначала распарсить все файлы по возможным параметрам, их сохранить в БД. В базе создать индексы и к базе писать web сервис
Я бы использовал Sphinx, позволяет очень тонко настроить поиск. Он создан как раз для таких задач. Конечно нужны знания или специалист. Язык большой роли не играет, я знаю php, сделал бы на нем. Дальше уже советовать нет смысла, нужно знать что вам конкретно надо, какие данные, сколько, обновляются ли они, как часто добавляются и т.д.
Забыл про базу. Опять же на ваш выбор, я бы выбрал MySql. Но есть вариант без базы, когда у вас есть текстовые файлы и Sphinx на прямую их индексирует. не знаю на сколько такой вариант вам походит.