我正在开发一个Zend Framework 2应用程序,应该提供:
还有两个主要实体:image
和project
,第一个想法是创建两个模块(Image
和Project
)并为每个模块提供一个单独搜索fuctionaly。但这意味着大量的重复代码。好吧,也许是一个单独的Search
模块?但是这个模块基本上取决于其他模块。
这种情况的好方法是什么?对此有最好的做法吗?
答案 0 :(得分:1)
我编写了一个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
是我的模型/实体可以使用的界面" make"它可以搜索。它让ES设置ES id并抓取类型。通常,每个实体都有自己的类型(因此我可以搜索所有图像和项目,或仅查询图像类型)。
我已经为博客/活动系统实现了这个功能。将博客文章保存到数据库中的服务类会触发事件,而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
(在搜索查询后返回)转换为{{1}再次反对。
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
答案 1 :(得分:0)
我会创建某种“搜索界面”,每个模块都会实现搜索自己的数据。然后你的搜索模块可以检查所有可用的模块,如果它们包含这个界面,如果有的话,用它来搜索他们的数据......
我猜测的缺点是搜索代码在每个模块中实现......