Symfony2 DoctrineMongoDBBundle一对多双向参考

时间:2012-09-02 23:26:43

标签: php mongodb symfony doctrine dbref

我正在尝试使用Symfony2和DoctrineMongoDBBundle在MongoDB中使用关系 根据{{​​3}}的第49张, 分配$User->setOrganization($Organization)足以使$Organization::users[0]引用用户对象就足够了。 在Doctrine MongoDB Object Document Mapper presentation中我说我必须使用inversedBy和mappedBy选项。 我有类似的方案(用户属于组),但我不能同时进行更新工作:

$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();

MongoDB中的结果:

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

用户

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

的src /的Myvendor / MongoBundle /文档/ 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 /文档/ 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;
    }
}

1 个答案:

答案 0 :(得分:1)

问题是为什么你在两个文件中都需要$ refs?这不是一种有效的方法,因为您需要分别维护两个对象。如果你真的需要它,那么你需要在两端设置引用。

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

第二个选项是仅在其中一个文档上保留$ ref。 Doctrine将为您处理所有工作。为此,您只需要设置反向和拥有方(不需要使用$group->addUsers($this);)。

对于用户:

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

对于小组:

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

使用the documentation比使用演示文稿更好。

ps:OP根据这个答案改变了问题。在低估正确答案之前检查历史记录。