私は fos:elastica を使用して Symfony2 プロジェクトに取り組んでいます。ユーザーは好きな場所をいいねしてフォローすることができます。デフォルトでは、ユーザーが場所を気に入ると、「フォロー中」アクションが自動的に追加されます。
まず最初に、これら 2 つのアクションをデータベース (doctrine2) に永続化します。私のデータはdbに正しく保存されています。
インデックス「user_action」を使用して ES クエリを作成すると、場所に関連するすべてのアクションが取得されます (前のようなものと次のもの)。
しかし、インデックス「場所」で同じことを行うと、最初のアクション(いいね)しか得られません。
ES は、提案オブジェクトで userAction を更新できていないようです。
一方、「次の」アクションを永続化するクエリを削除し (いいねの後に自動的に追加されます)、(API を介して) 2 番目の呼び出しを行うと、アクションは db に保存され、代わりにオブジェクトも更新されます。
誰かが私が言ったことと私がやろうとしていることを理解してくれることを願っています^^
マッピング
場所
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());
}
}
}
現在の結果
ネストされたオブジェクト userAction で場所を取得 (#320)
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
}
]
}
}
]
ID #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();
に
$em = $this->getEntityManager();
$em->persist($like);
$em->persist($following);
$em->flush();
そしてそれは働いています!!!!
これが誰かを助けることを願っています。