Стратегии поиска в ORM
Вопрос
Я ищу информацию об обработке поиска в различных ORM.
В настоящее время я переделываю старое приложение на PHP, и одно из требований:Сделайте все или почти все доступным для поиска: пользователь просто вводит «панк-рок в прямом эфире», и приложение находит видеоклипы, музыкальные треки, обзоры, предстоящие события или даже комментарии пользователей, помеченные таким образом.
В среде, где все доступно для поиска, ORM необходимо поддерживать эту функцию двумя способами:
- предоставление некоторого API индексирования на стороне «O» ORM
- предоставление средств для массового извлечения данных из базы данных на стороне «R»
Идеальным решением было бы возвращать готовые объекты на основе искомой строки.Знаете ли вы какие-нибудь хорошие комплексные решения, которые выполняют эту работу, не обязательно на PHP?Если вы сталкивались с подобной проблемой, было бы неплохо услышать ваш опыт.Что-то большее, чем Используйте Люсен или семантическая сеть - это путь однолайнеры, хотя ;-)*
Решение
Недавно я интегрировал Компас поисковую систему в приложение Java EE 5.Он основан на Лусене Ява и поддерживает различные платформы ORM, а также другие типы моделей, такие как XML или вообще отсутствие реальной модели;)
В случае объектной модели, управляемой платформой ORM, вы можете аннотировать свои классы специальными аннотациями (например,@Searchable), зарегистрируйте свои классы и позвольте Compass индексировать их при запуске приложения и автоматически прослушивать изменения в модели.
Когда дело доходит до поиска, у вас под рукой есть возможности Lucene.Затем Compass предоставляет вам экземпляры объектов вашей модели в качестве результата поиска.
Это не PHP, но вы сказали, что это не обязательно должен быть PHP;) Хотя не знаю, поможет ли это...
Другие советы
В файле схемы.xml Propel 1.3 вы можете указать, что вы хотите, чтобы все ваши модели расширяли класс «BaseModel», который ВЫ создаете.
В этой BaseModel вы собираетесь переопределить метод save() примерно так:
public function save(PropelPDO $con = null)
{
if($this->getIsSearchable())
{
// update your search index here. Lucene, Sphinx, or otherwise
}
return parent::save($conn);
}
Это заботится о том, чтобы все было проиндексировано.Что касается поиска, я бы предложил создать класс Search с несколькими методами.
class Search
{
protected $_searchableTypes = array('music','video','blog');
public method findAll($search_term)
{
$results = array();
foreach($this->_searchableTypes as $type)
{
$results[] = $this->findType($type, $search_term);
}
return $results;
}
}