2012-09-05 13 views
6

文書が埋め込まれている文書があります。初めてオブジェクトを作成すると、すべて正常に動作しますが、ドキュメントを更新しようとすると、埋め込みドキュメントは更新されません。Doctrine MongoDBの埋め込みドキュメントを更新するにはどうすればよいですか?

/** @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に埋め込みドキュメントの値を見て更新する必要があるかどうかを判断する方法がありますか?

答えて

0

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

2

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

$document->getDocB()->setValueB('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(); 

これは、作業単位が新しく設定された文書として$文書のdocBを認識させると予想されるとして、それをフラッシュします。

+0

埋め込みドキュメントを別のドキュメントに置き換える際に問題が発生しました。私の場合、DocumentBは組み込みドキュメントではなく、ドキュメントです。あなたがここに示したようなオブジェクトでデタッチを使用することは、このシナリオでも同様に働きました。 – Onema

関連する問題