3

構造を持つmongodbドキュメント(ノードと呼ばれる)にマッピングするphpオブジェクトがあります

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

class Node{
    /**
    * @MongoDB\Id
    */
    protected $id;

    /**
    * @MongoDB\String
    */
    protected $domain;

    /**
    * @MongoDB\ReferenceMany(targetDocument="NodeItem",cascade=     
    * {"persist"},simple="true")
    */
    protected $items = array();

    //getter and setters below
}

そして、NodeItemと呼ばれる参照ドキュメント、

class NodeItem {

  /**
  * @MongoDB\Id
  */
  protected $id;

  /**
  * @MongoDB\String
  */
  protected $name;

  /**
   * @MongoDB\ReferenceOne(targetDocument="Node", cascade={"persist"},    
   *  simple="true")
   */
   protected Node;

   //setter and getters 
}

上記の注釈に反映されているように、「Node」は$ items配列に格納されている多くの「NodeItems」を参照し、「NodeItems」は1つの「Node」を参照します。したがって、これらは双方向の参照コレクションです。

私の質問は、コレクションからいくつかの「NodeItem」ドキュメントを効果的に削除して(使用可能なIDの配列に基づいて)、削除されたNodeItemドキュメントも「Node」の$ items配列参照から削除されるようにする方法です(カスケード削除だと思います)私が求めているのは何ですか?)

私はこのようなコードを持つ関数を書きました:

   $qb = $this->dm->createQueryBuilder('SomeBundleBundle:NodeItem');
    /*
     * deletes from NodeItem collection
     */
    foreach($NodeItemsArray as $itemId){
        $qb->remove()->field('id')->equals($itemId)->getQuery()->execute();
    }

ただし、上記の関数はNodeItemコレクションからドキュメントを削除するだけで、「Node」の$items配列内の関連アイテムは削除されません。また、アノテーションの{cascade:persist}は役に立たないようです。コードはSymfony2フレームワークに実装されています

いくつかの助けをいただければ幸いです!

4

2 に答える 2

0

ODM でのカスケード動作は、UnitOfWork 操作によってのみ尊重されます。MongoDB はカスケードとトリガーをネイティブにサポートしていません (とにかく)。あなたの場合、クエリビルダーは次のようなクエリを作成して実行します:

db.node_items.remove({"_id": ObjectId("...")})

UnitOfWork はまったく関与せず (段階的な操作やフラッシュはありません)、カスケードはトリガーされません。

一方、管理$nodeItem対象オブジェクトがあるとします。これを に渡すと、DocumentManager::remove()UnitOfWork が呼び出され、マップされた参照ドキュメントcascade=REMOVEまたはcascade=ALL削除される参照ドキュメントが発生します。もちろん、flush()MongoDB で操作を実行するために呼び出す必要があります。

現在のコードに基づくと、カスケードされる唯一の操作はDocumentManager::persist(). 実際には、Node を作成し、そこにいくつかの NodeItems を構築して追加し、Node を永続化する (その項目を自動的に永続化できるようにする) と仮定します。

NodeItems が単一の Node にのみ属している場合は、それ自体を削除した後cascade=REMOVE、.$nodeItem->getNode()->getItems()->removeElement($nodeItem)$nodeItemflush()

また、コレクション フィールドを配列に初期化していることにも気付きました。後で、ODM はこのフィールドをDoctrine\ODM\MongoDB\PersistentCollectionインスタンスとしてハイドレートするため、あいまいさが生じる可能性があります。Doctrine\Common\Collections\ArrayCollectionベスト プラクティスとして、コンストラクターなどでフィールドを初期化する必要があります。そうすれば、それらが常にCollectionインスタンスであると期待できます。

于 2012-05-16T22:18:54.240 に答える