27/05/2016 - ELASTICSEARCH, SYMFONY
Eğer FOSElasticaBundle kullanıyorsanız, listener
seçeneğinin varsayılan değerinin, veritabanındaki bir object üzerinde yapılan değişikliklerden sonra elasticsearch listenerin indexi yenilemesi için ayarlandığını bilirsiniz. Bu ayar config dosyasında listener: ~
olarak belirtilmiştir. Bu işlemi manuel olarak yapmak isterseniz, aşağıdaki örneği kullanabilirsiniz.
Bu örneğimizde elimizde bulunan "Post" objesi üzerinde ekleme, yenileme ve silme işlemlerini yapacağız ve arka planda ise event subscriber ile elasticsearch indexini yenileyeceğiz.
Not: Size bu versiyonu kullanmanız yerine, diğer bir yazısını yazdığım ve daha da kısa olan event listener versiyonunu kullanmanızı tavsiye ederim.
fos_elastica:
clients:
default: { host: 127.0.0.1, port: 9200 }
indexes:
post_index:
client: default
index_name: post_dev
types:
post:
mappings:
id:
type: integer
index: not_analyzed
title:
type: string
analyzer: english
year:
type: integer
index: not_analyzed
price:
type: double
index: not_analyzed
is_published:
type: boolean
index: not_analyzed
persistence:
driver: orm
model: Application\SearchBundle\Entity\Post
finder: ~
provider: ~
listener: ~
namespace Application\SearchBundle\Service;
...........
...........
class PostDatabaseService
{
...........
...........
public function createPost()
{
$post = new Post();
$post->setTitle('inanzzz');
$post->setYear(1999);
$post->setPrice(6.99);
$post->setIsPublished(true);
$this->entityManager->persist($post);
$this->entityManager->flush();
return sprintf('create-post ID: %s', $post->getId());
}
public function updatePost($id)
{
/** @var Post $post */
$post = $this->findPost($id);
$post->setTitle('inanzzz inanzzz');
$this->entityManager->flush();
return sprintf('update-post ID: %s', $id);
}
public function deletePost($id)
{
/** @var Post $post */
$post = $this->findPost($id);
$this->entityManager->remove($post);
$this->entityManager->flush();
return sprintf('delete-post ID: %s', $id);
}
private function findPost($id)
{
$post = $this->postRepository->findOneById($id);
if (!$post instanceof Post) {
throw new EntityNotFoundException(sprintf('Post [%s] cannot be found.', $id));
}
return $post;
}
}
Bazı işlemlerin aslında nasıl yapıldığını görmek isterseniz vendor/friendsofsymfony/elastica-bundle/Doctrine/Listener.php
dosyasını okumanızı tavsiye ederim.
namespace Application\SearchBundle\Subscriber;
use Application\SearchBundle\Entity\Post;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\IndexableInterface;
class PostIndexSubscriber implements EventSubscriber
{
/** @var ObjectPersisterInterface */
private $postPersister;
/** @var IndexableInterface */
private $indexable;
private $events;
private $config;
private $scheduledForInsert;
private $scheduledForUpdate;
private $scheduledForDelete;
public function __construct(
ObjectPersisterInterface $postPersister,
IndexableInterface $indexable,
array $events,
array $config
) {
$this->postPersister = $postPersister;
$this->indexable = $indexable;
$this->events = $events;
$this->config = $config;
}
public function getSubscribedEvents()
{
return $this->events;
}
public function postPersist(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Post) {
if ($this->postPersister->handlesObject($entity)) {
if ($this->isObjectIndexable($entity)) {
$this->scheduledForInsert = $entity;
}
}
}
}
public function postUpdate(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Post) {
if ($this->postPersister->handlesObject($entity)) {
if ($this->isObjectIndexable($entity)) {
$this->scheduledForUpdate = $entity;
}
}
}
}
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Post) {
if ($this->postPersister->handlesObject($entity)) {
$this->scheduledForDelete = $entity->getId();
}
}
}
public function postFlush()
{
if ($this->scheduledForInsert) {
$this->postPersister->insertOne($this->scheduledForInsert);
$this->scheduledForInsert = null;
}
if ($this->scheduledForUpdate) {
$this->postPersister->replaceOne($this->scheduledForUpdate);
$this->scheduledForUpdate = null;
}
if ($this->scheduledForDelete) {
$this->postPersister->deleteById($this->scheduledForDelete);
$this->scheduledForDelete = null;
}
}
private function isObjectIndexable($object)
{
return $this->indexable->isObjectIndexable(
$this->config['index'],
$this->config['type'],
$object
);
}
}
services:
application_search.subscriber.post_index:
class: Application\SearchBundle\Subscriber\PostIndexSubscriber
arguments:
- @fos_elastica.object_persister.post_index.post
- @fos_elastica.indexable
- [ postPersist, postUpdate, preRemove, postFlush ]
- { index: post_index, type: post }
tags:
- { name: doctrine.event_subscriber }