嵌入文档的 Doctrine Mongodb getOriginalDocumentData

Doctrine Mongodb getOriginalDocumentData on embedded document

在我的 symfony 应用程序中,我有我的 event_subscriber

CoreBundle\EventSubscriber\CloseIssueSubscriber:
        tags:
            - { name: doctrine_mongodb.odm.event_subscriber, connection: default }

我的订阅者只听 postPersist 和 postUpdate 事件:

public function getSubscribedEvents()
    {
        return array(
            'postPersist',
            'postUpdate',
        );
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $this->index($args);
    }

    public function postUpdate(LifecycleEventArgs $args)
    {
        $this->index($args);
    }

在我的索引函数中,我需要做的是获取某个字段是否已更改,尤其是 issue.status 字段。

public function index(LifecycleEventArgs $args)
    {
        $document = $args->getEntity();

            $originalData = $uow->getOriginalDocumentData($document);

            $originalStatus = $originalData && !empty($originalData['issue']) ? $originalData['issue']->getStatus() : null;
            var_dump($originalStatus);
            var_dump($document->getIssue()->getStatus());die;
    }

在我的测试中,我所做的是更改 issue.status 字段,因此我希望从 var_dump 中接收到 2 个不同的值,但我却从两者中获得了最后一个状态。

我的文档就是这样的:

class Payload
{
/**
 * @ODM\Id
 */
private $id;

/**
 * @ODM\EmbedOne(targetDocument="CoreBundle\Document\Issue\Issue")
 * @Type("CoreBundle\Document\Issue\Issue")
 */
protected $issue;

}

在嵌入式问题文档状态中只是一个文本字段。

我也尝试使用变更集:

$changeset = $uow->getDocumentChangeSet($document);
foreach ($changeset as $fieldName => $change) {
   list($old, $new) = $change;
}
var_dump($old->getStatus());
var_dump($new->getStatus());

这两个var_dump也是returns一样的状态。

postUpdate 时,文档中的更改已经完成,因此 originalDocumentData 已调整并准备好进行新的计算。相反,您应该挂接到 preUpdate 事件并在那里使用 $uow->getDocumentChangeSet($document);

我猜你想要 运行 index 一旦更改被写入数据库,所以 preUpdate 你可以在监听器中累积更改并另外挂接到 postFlush 事件到 re-index 文档。

我找到了解决问题的方法。 malarzm 在另一个答案中说的是正确的,但不是我问题的解决方案。
我想我只为文档(有效负载)得到一个 postUpdate/preUpdate postPersist/prePersist 而不是我注意到它被称为嵌入式文档的事件(不知道为什么学说认为它是持久的)。

所以主要问题是我在等待 Payload 对象,而不是我必须等待 Issue 对象。
另一方面,即使在 postUpdate 和 preUpdate 中,我也无法正确使用 getOriginalDocumentData,所以我必须使用 getDocumentChangeSet()。