6

ドキュメントが埋め込まれたドキュメントがあります。初めてオブジェクトを作成するとすべて正常に動作しますが、ドキュメントを更新しようとすると、埋め込まれたドキュメントが更新されません。

/** @MongoDB\Document */
class DocumentA
{
    /** @MongoDB\EmbedOne(targetDocument="DocumentB") **/
    protected $docB;

    /** @MongoDB\String */
    protected $valueA;
}

/** @MongoDB\EmbeddedDocument */
class DocumentB
{
    /** @MongoDB\String */
    protected $valueB;
}

私のアプリケーションでは、ドキュメントに対してクエリを実行し、値を更新してデータ ストアに永続化します。

// Variant A – Does not work
$document = ... // find from data store
$document->setValueA('Hello World');
$document->getDocB()->setValueB('foo baz');

$om->persist($document);
$om->flush();

埋め込みドキュメントを更新せずに新しいドキュメントを設定すると、すべて正常に動作します。

// Variant B - Does work
$document = ... // find from data store
$document->setValueB('Hello World 2');
$document->setDocB(new DocumentB());
$document->getDocB()->setValueB('foo baz 2');

$om->persist($document);
$om->flush();

私が言ったように、バリアント B は正常に動作します。しかし、私のアプリケーションではドキュメントがより複雑であり、埋め込みドキュメントを更新する必要があるたびに新しいオブジェクトを作成するのは現実的ではありません。Doctrine ODM に埋め込まれたドキュメントの値を調べて、更新する必要があるかどうかを判断するように指示する方法はありますか?

4

2 に答える 2

2

私はまったく同じ問題に直面しました。UnitOfWork は、他のドキュメントが埋め込まれたドキュメントのチェンジセットの計算に失敗しているように見えますが、その理由を理解することはできませんでした...結果として、実際の値と元の値を比較すると、ユニットの仕事は両方に同じ値を示します。バリアント A と話すとき、

$document->getDocB()->setValueB('foo baz');

作業単位は、古い値と新しい値の両方に対して「foo baz」を示し、それを変更として認識しないため、更新しません。

とにかく、これは回避策につながります:

$document = ... // find from data store
$document->setValueA('Hello World');
$docB = $document->getDocB();
$docB->setValueB('foo baz');
$om->detach($docB);
$om->persist($document);
$om->flush();

これにより、作業ユニットは $document の docB を新しく設定されたドキュメントとして認識し、期待どおりにフラッシュします。

于 2013-03-20T13:29:58.557 に答える
0

MongoDB にはアトミック操作しかありません。次のオプションがあります。 1. ドキュメントを照会し、適切なサブドキュメントを見つけ、ドキュメント全体またはその一部を更新します。長所: 簡単なロジック 短所: 非アトミック 2. サブドキュメントがリストにある場合は、位置 $ 演算子を使用します。

于 2013-02-04T11:02:47.587 に答える