Я разрабатываю приложение Zend Framework 2, которое должно обеспечить:
Также есть две основные сущности: image
а также project
и первой идеей было создать два модуля (Image
а также Project
) и дать каждому из них отдельный поиск по желанию. Но это будет значить много дублированного кода. Хорошо, может быть отдельный Search
модуль? Но тогда этот модуль будет существенно зависеть от других модулей.
Что было бы хорошим подходом для такого случая? Есть ли лучшая практика для этого?
Я написал модуль упругого поиска ZF2, но это закрытый источник. Это позволяет модулям помещать доступные для поиска данные в ES. Я не могу опубликовать код, но я могу объяснить, как он работает.
Центральный модуль Search
, Поиск содержит два основных интерфейса: Search\Repository\ItemRepositoryInterface
а также Search\Service\ItemServiceInterface
, Хранилище для поиска предметов, сервис для хранения / удаления предметов.
interface ItemRepositoryInterface
{
public function search($query, $limit = 10);
}
interface ItemServiceInterface
{
public function insert(SearchableInterface $object);
public function remove(SearchableInterface $object);
}
SearchableInterface
это интерфейс, который мои модели / сущности могут использовать для «поиска». Это позволит ES установить идентификатор ES и захватить тип. Обычно каждый объект получает свой собственный тип (поэтому я могу искать все изображения и проекты или запрашивать только типы изображений).
Я реализовал это для системы блогов / событий. Класс обслуживания, который сохраняет статью блога в базе данных, вызывает события, и ElasticSearch является одним из слушателей:
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$em = $app->getSharedManager();
$em->attach('Blog\Service\ArticleService', 'create', function($e) use ($sm) {
$searchService = $sm->get('Search\Service\ItemService');
$article = $e->getArticle();
$searchService->insert($article);
});
}
Так как Article
инвентарь SearchableInterface
это прекрасно работает. Теперь мой блог не должен иметь дело с поиском, а поиск не должен иметь дело с блогом. Интересно, а как статья преобразуется в поисковый документ?
У меня есть гидраторный механизм, который работает как гидратор ZF2. Он не конвертирует какой-либо объект в массив (и наоборот). Это превращает SearchableInterface
объект в упругом поиске Document
(для хранения объекта) и он преобразует упругий поиск Result
(который возвращается после поискового запроса) в SearchableInterface
объект снова
interface HydratorInterface
{
public function extract(SearchableInterface $object);
public function hydrate(Result $object);
}
Каждый тип имеет свой собственный зарегистрированный гидратор. Все эти разные гидраторы собраны в HydratorManager
который в основном Zend\ServiceManager\AbstractPluginManager
, Этот менеджер плагинов внедряется в хранилище и сервис.
Итак, внутри сервиса происходит следующее:
$object->getType()
провереноextract()
призван повернуть $object
в $document
$object->getElasticSearchId()
Для хранилища дан запрос type:image name:Mountain
происходит следующее:
search()
вызывается по заданному запросуhydrate()
призван повернуть $result
в $object
Я хотел бы создать своего рода «интерфейс поиска», который каждый модуль будет реализовывать для поиска своих данных. Тогда ваш поисковый модуль может проверить все доступные модули, если они содержат этот интерфейс, и если они есть, использовать его для поиска своих данных …
Недостаток, я думаю, в том, что код поиска реализован в каждом модуле …