2

I'm trying to use relations in MongoDB, using Symfony2 and DoctrineMongoDBBundle According slide 49 of the Doctrine MongoDB Object Document Mapper presentation, it's enough to assign $User->setOrganization($Organization), to make $Organization::users[0] referred to user object. In the documentation says i have to use inversedBy and mappedBy options. I have the similar scheme (User belongs to Group), but I can't get both update work:

$Group = new \MyVendor\MongoBundle\Document\Group();
$User = new \MyVendor\MongoBundle\Document\User();
$User->setGroup($Group);
/** @var \Doctrine\ODM\MongoDB\DocumentManager $dm */
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($Group);
$dm->persist($User);
$dm->flush();

Results in MongoDB:

Group

{
   "_id": ObjectId("5043e24acdc2929a0500000d"),
}

User

{
   "_id": ObjectId("5043e24acdc2929a0500000c"),
   "group": {
     "$ref": "Group",
     "$id": ObjectId("5043e24acdc2929a0500000d"),
     "$db": "my_db" 
  }
}

src/MyVendor/MongoBundle/Document/User.php

<?php
namespace MyVendor\MongoBundle\Document;

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

/**
 * @MongoDB\Document(repositoryClass="MyVendor\MongoBundle\Repository\UserRepository")
 */
class User
{
    /**
    * @MongoDB\Id
    */
    private $id;

    /**
     * @var
     * @MongoDB\ReferenceOne(targetDocument="Group", inversedBy="users")
     */
    private $group;

    /**
     * Set group
     *
     * @param MyVendor\MongoBundle\Document\Group $group
     * @return User
     */
    public function setGroup(\MyVendor\MongoBundle\Document\Group $group)
    {
        $this->group = $group;
        return $this;
    }
}

src/MyVendor/MongoBundle/Document/Group.php

<?php
namespace MyVendor\MongoBundle\Document;

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

/**
 * @MongoDB\Document
 */
class Group
{

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

    /**
     * @MongoDB\ReferenceMany(targetDocument="User", mappedBy="group")
     * @var User[]
     */
    private $users;

    public function __construct()
    {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add users
     *
     * @param MyVendor\MongoBundle\Document\User $users
     */
    public function addUsers(\MyVendor\MongoBundle\Document\User $users)
    {
        $this->users[] = $users;
    }
}
karser
  • 1,625
  • 2
  • 20
  • 24

1 Answers1

1

The question is why do you need $refs in both documents? That's not an effective way because you need to maintain two objects separately. If you really need it, then you need to set references on both ends.

public function setGroup(\MyVendor\MongoBundle\Document\Group $group)
{
    $this->group = $group;
    $group->addUsers($this);
    return $this;
}

The second option is to keep $ref only on one of the documents. Doctrine will handle all the job for you. For this to work you only need to set inverse and owning side (don't need to use $group->addUsers($this);).

For user:

* @MongoDB\ReferenceOne(targetDocument="Group", inversedBy="users")

For Group:

* @MongoDB\ReferenceMany(targetDocument="User", mappedBy="group")

And it's always better to use the documentation than presentations.

ps: the OP changed the question according to this answer. Check the history before downvoting correct answers.

meze
  • 14,975
  • 4
  • 47
  • 52
  • To use inversedBy and mappedBy it's probably my aim, i've already tried that the way exactly you pointed, but it doesn't work for me, probably something wrong.. – karser Sep 03 '12 at 06:45