Home:ALL Converter>How to delete document from a referenced array of documents in doctrine ODM with mongodb

How to delete document from a referenced array of documents in doctrine ODM with mongodb

Ask Time:2012-05-17T01:26:15         Author:krishna

Json Formatter

I have a php object mapping to a mongodb document(called Node) with a structure

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
}

And a referenced document called, NodeItem,

class NodeItem {

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

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

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

   //setter and getters 
}

As reflected by the annotations above 'Node' references MANY 'NodeItems' stored in a $items array and 'NodeItems' references ONE 'Node'. So those are bi-directional referenced collections.

My Question is how to effectively delete a few 'NodeItem' documents from its collection (based on the array of available ids), so that the deleted NodeItem documents are also deleted from the $items array references in 'Node' (cascaded delete I think is what I am asking for?).

I wrote a function that has code like this :

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

But the above function only deletes the documents from NodeItem collection, but the associated items in the $items array of 'Node' are not deleted. Also, the {cascade:persist} in the annotations doesn't seem to help. The code is implemented in Symfony 2 framework

Some help is appreciated !

Author:krishna,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/10623577/how-to-delete-document-from-a-referenced-array-of-documents-in-doctrine-odm-with
Madarco :

The only way to achieve that is with a listener on the onRemove event.\n\nBut has mentioned by @jmikola, you'll have to use the $dm->remove() method, and not the QueryBuilder (since it doesn't support events yet).\n\n\n\nso, to delete the Item do:\n\n//Get the NodeItem you want in the items array and delete it:\n$items = $node->getItems();\n$dm->remove($items->get(2)); //Remove the third item as an example\n\n\n\n\nAnd register the event:\n\nclass CascadeNodeDeleterListener {\n public function preRemove(LifecycleEventArgs $eventArgs) {\n\n $odm = $eventArgs->getDocumentManager(); /* @var $odm DocumentManager */\n $object = $eventArgs->getDocument();\n if($object instanceOf NodeItem) {\n $node = $object->getNode();\n $items = $node->getItems();\n $items->removeElement($object);\n $class = $dm->getClassMetadata(get_class($node));\n $dm->getUnitOfWork()->recomputeSingleDocumentChangeSet($class, $node);\n }\n\n }\n}\n\n\nIn services.yml:\n\n <service id=\"listener\" class=\"CascadeNodeDeleterListener\">\n <tag name=\"doctrine.common.event_listener\" event=\"onRemove\" />\n </service>\n\n\nSee Doctrine ODM Events from more info.",
2013-05-01T07:36:54
yy