doctrine / search
此包已被弃用且不再维护。未建议替代包。
ElasticSearch 和 Solr 实体映射库
v0.2
2016-11-17 17:48 UTC
Requires
- php: >=5.3.2
- doctrine/common: >=2.3.0
Requires (Dev)
- doctrine/orm: ~2.4
- phpunit/phpunit: ~4.2
Suggests
- ruflin/Elastica: Elastica version correlating to your ElasticSearch installation is required.
- symfony/yaml: If you want to use YAML Metadata Mapping Driver
This package is not auto-updated.
Last update: 2022-05-06 15:13:18 UTC
README
注意:该项目目前是一个原型。有关实际实现示例,请参阅 demo
文件夹。
支持的搜索引擎
- ElasticSearch(功能支持)
- Solr(部分实现)
功能
- SearchManager
- 可独立使用或混合配置使用
- 可配置的搜索管理器支持聚合实体管理器
- 通过搜索引擎适配器(如 Elastica)直接进行 API 调用
- 通过批量操作将返回的 ID 转换为所需的填充对象
- 支持事件管理器监听器以自定义实体处理
- 通过 JMS Serializer 或简单的实体回调通过事件监听器进行索引
- 使用 ObjectManager::getClassMetadata() 作为基础结构创建索引和数据类型的注解
#用法#
配置
以下示例显示了如何配置搜索管理器连接
$config = new Doctrine\Search\Configuration(); $config->setMetadataCacheImpl(new Doctrine\Common\Cache\ArrayCache()); $config->setEntitySerializer( new Doctrine\Search\Serializer\JMSSerializer( JMS\Serializer\SerializationContext::create()->setGroups('search') ) ); $eventManager = new Doctrine\Search\EventManager(); $eventManager->addListener($listener); $searchManager = new Doctrine\Search\SearchManager( $config, new Doctrine\Search\ElasticSearch\Client( new Elastica\Client(array( array('host' => 'localhost', 'port' => '9200') ) ), $eventManager );
映射
以下示例显示了索引和类型生成的基本实体映射。映射可以通过构建脚本来渲染成适合自动生成索引和类型的格式(需要高级设置)。
<?php namespace Entities; use Doctrine\Search\Mapping\Annotations as MAP; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @MAP\ElasticSearchable(index="indexname", type="post", source=true) */ class Post { /** * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") * @MAP\ElasticField(type="integer", includeInAll=false) */ private $id; /** * @ORM\Column(type="string") * @MAP\ElasticField(type="string", includeInAll=true, boost=5.0) */ private $title; /** * @ORM\Column(type="text") * @MAP\ElasticField(type="string", includeInAll=true) */ private $content; /** * @MAP\ElasticField(name="tags", type="string", includeInAll=false, index="not_analyzed") */ public function getTags() { return $this->tags->slice(0,3); } }
索引
目前可以通过以下方式对文档进行序列化以进行索引。如果需要,可以使用与 ORM 一起使用的事件监听器,如下例所示。如果不需要事件监听器,则可以直接使用搜索管理器对实体进行持久化或删除。
<?php namespace Entities\Listener; use Doctrine\ORM\Event\LifecycleEventArgs; use Entities\Behaviour\SearchableEntityInterface; class SearchableListener implements { protected function getSearchManager() { return $this->getDatabaseConnection('elasticsearch'); } public function postPersist(LifecycleEventArgs $oArgs) { $oEntity = $oArgs->getEntity(); if($oEntity instanceof SearchableEntityInterface) { $this->getSearchManager()->persist($oEntity); } } public function postRemove(LifecycleEventArgs $oArgs) { $oEntity = $oArgs->getEntity(); if($oEntity instanceof SearchableEntityInterface) { $this->getSearchManager()->remove($oEntity); } } }
CallbackSerializer
此方法仅期望实体上的 toArray()
方法,尽管可以根据需要进行配置。示例中建议的接口可以是任何您想要的接口,只要您的事件监听器可以识别需要持久化到搜索引擎的实体(请参阅上面的示例)。
... use Entities\Behaviour\SearchableEntityInterface class Post implements SearchableEntityInterface { ... public function toArray() { return array( 'id' => $this->id, 'title' => $this->title, 'content' => $this->content ... ); } }
JMS Serializer
您还可以使用 JMS Serializer
的高级序列化功能来自动处理序列化,如以下示例所示。
... use JMS\Serializer\Annotation as JMS; use Entities\Behaviour\SearchableEntityInterface /** * @ORM\Entity * @MAP\ElasticSearchable(index="indexname", type="post", source=true) * @JMS\ExclusionPolicy("all") */ class Post implements SearchableEntityInterface { ... /** * @ORM\Column(type="string") * @MAP\ElasticField(type="string", includeInAll=true, boost=5.0) * @JMS\Expose * @JMS\Groups({"public", "search"}) */ private $title; /** * @ORM\Column(type="text") * @MAP\ElasticField(type="string", includeInAll=true) * @JMS\Expose * @JMS\Groups({"public", "search"}) */ private $content; ... }
AnnotationSerializer
尚不可用。
查询
可以通过以下方式通过搜索管理器执行查询。使用结果缓存的用法是指使用缓存进行填充查询。搜索引擎特定的适配器接口被神奇地暴露出来,因此在这个示例中,Elastica\Query::addSort
方法与 Doctrine\Search\Query
方法合并。因此,任何由搜索引擎客户端库支持的查询复杂性都受到支持。
$hydrationQuery = $entityManager->createQueryBuilder() ->select(array('p', 'field(p.id, :ids) as HIDDEN field')) ->from('Entities\Post', 'p') ->where('p.id IN (:ids)') ->orderBy('field') ->getQuery(); $query = $searchManager->createQuery() ->from('Entities\Post') ->searchWith(new Elastica\Query()) ->hydrateWith($hydrationQuery) ->addSort('_score') ->setFrom(0) ->setLimit(10) ->getResult();
可以使用以下技术进行简单的存储库ID查询和Term
搜索。反序列化独立于Doctrine\ORM
进行,但根据注册的SerializerInterface
,相同的模型被相应地填充。
$entity = $searchManager->getRepository('Entities\Post')->find($id); $entity = $searchManager->getRepository('Entities\Post')->findOneBy(array($key => $term));