Я работаю над проектом Symfony2 с fos:elastica. Пользователи могут ставить лайки и подписываться на места, которые им нравятся. По умолчанию, когда пользователю нравится место, мы автоматически добавляем действие «подписаться».
Итак, прежде всего, я сохраняю эти 2 действия в базе данных (doctrine2). Мои данные правильно сохраняются в БД.
Когда я делаю запрос ES с индексом «user_action», я получаю все действия, связанные с местом (предыдущее и следующее).
Но когда я делаю то же самое с индексом «место», я получаю только первое действие (например).
Кажется, ES не удается обновить userAction в объекте предложения.
С другой стороны, если я удаляю запрос, который сохраняет «следующее» действие (добавляется автоматически после лайка), и я делаю второй вызов (через API), мое действие сохраняется в БД, а также обновляется на месте объекта.
Надеюсь, кто-нибудь поймет, что я сказал и что я пытаюсь сделать ^^
Отображение
Место
place:
mappings:
id:
type: integer
userAction:
type: nested
properties:
userId:
type: integer
userActionTypeId:
type: integer
userActionType:
type: nested
properties:
name:
type: string
Действие пользователя
user_action:
mappings:
userId:
type: integer
placeId: ~
place:
type: nested
properties:
id:
type: integer
userActionType:
type: nested
properties:
name: ~
Слушатель
Услуга
`fos_elastica.listener.place.user_action`:
class: API\Rest\v1\PlaceBundle\EventListener\ElasticaUserActionListener
arguments:
- @fos_elastica.object_persister.search.user_action
- ['postPersist', 'postRemove']
- @fos_elastica.indexable
calls:
- [ setContainer, ['@service_container', @fos_elastica.object_persister.search.place ] ]
tags:
- { name: 'doctrine.event_subscriber' }
Класс
<?php
namespace API\Rest\v1\PlaceBundle\EventListener;
use Doctrine\Common\EventArgs;
use FOS\ElasticaBundle\Doctrine\Listener as BaseListener;
use FOS\ElasticaBundle\Persister\ObjectPersister;
use Symfony\Component\DependencyInjection\ContainerInterface;
use API\Rest\v1\UserActionBundle\Entity\UserAction;
class ElasticaUserActionListener extends BaseListener
{
private $container;
private $objectPersisterSuggestion;
public function setContainer(ContainerInterface $container, ObjectPersister $objectPersisterSuggestion)
{
$this->container = $container;
$this->objectPersisterPlace = $objectPersisterPlace;
}
public function postPersist(EventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof UserAction) {
$this->scheduledForInsertion[] = $entity;
$this->objectPersisterPlace->replaceOne($entity->getPlace());
}
}
public function postRemove(EventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof UserAction) {
$this->scheduleForDeletion($entity);
$this->objectPersisterPlace->replaceOne($entity->getPlace());
}
}
}
Текущий результат
Получить место (#320) с вложенным объектом userAction
query : http://localhost:9200/search/place/_search
"hits" : [
{
"_index" : "search",
"_type" : "place",
"_id" : "320",
"_score" : 5.7004805,
"_source":{
"userAction":[
{
"userActionType":{
"name":"like"
},
"userActionTypeId":3,
"userId":3
}
]
}
}
]
Получить действие пользователя, связанное с местом с идентификатором # 320
query : http://localhost:9200/search/user_action/_search
"hits" : [
{
"_index" : "search",
"_type" : "user_action",
"_id" : "50",
"_score" : 5.7004805,
"_source" : {
"userId" : 4,
"placeId" : 320,
"userActionType" : {
"name" : "following"
}
}
},
{
"_index" : "search",
"_type" : "user_action",
"_id" : "49",
"_score" : 5.402646,
"_source" : {
"userId" : 4,
"placeId" : 320,
"userActionType" : {
"name" : "like"
}
}
}
]
ОБНОВЛЕНИЕ (решение)
Наконец-то я нахожу правильный способ сделать это. Я слишком рано сбрасывал данные.
Я заменил этот неправильный код
$em = $this->getEntityManager();
$em->persist($like);
$em->flush();
$em = $this->getEntityManager();
$em->persist($following);
$em->flush();
by
$em = $this->getEntityManager();
$em->persist($like);
$em->persist($following);
$em->flush();
и это работает!!!!
Надеюсь, это может помочь кому-то.