Symfony 2 Doctrine ODM参考

时间:2013-11-19 15:04:51

标签: php mongodb symfony doctrine-orm doctrine-odm

所以我有以下两个文件:

壁纸

/**
 * @MongoDB\Document(
 *    collection="wallpapers",
 *    repositoryClass="Application\Bundle\DefaultBundle\Repository\WallpaperRepository"
 * )
 */
class Wallpaper
{
    /**
     * @MongoDB\Id(strategy="auto")
     * @var string $id
     */
    private $id;

    /**
     * @var ArrayCollection
     *
     * @MongoDB\ReferenceMany(
     *     targetDocument="Category"
     * )
     *
     * 
     */
    private $categories;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->categories = new ArrayCollection();
    }
}

分类

/**
 * @MongoDB\Document(collection="categories")
 */
class Category
{

    /**
     * @MongoDB\Id(strategy="auto")
     * @var string $id
     */
    private $id;

    /**
     * @MongoDB\Field(type="boolean")
     *
     * @var bool $published
     */
    private $published;
}

我需要选择所有仅包含已发布类别的壁纸... 我尝试了很多解决方案,我通过Google搜索找到了解决方案但仍未找到解决我问题的方法......

这是我的查询:

$wallpapers = $this->createQueryBuilder('ApplicationDefaultBundle:Wallpaper')
            ->field('categories.published')->equals(true)
            ->getQuery()
            ->execute()

但它不起作用:(

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

在关系数据库上,你可以通过加入来实现,但是在mongodb中你可以:


在壁纸文档中对您引用的类别进行反规范化:

/**
 * @MongoDB\EmbedMany(targetDocument="Category")
 */
private $categories;

(注意EmbedMany)

通过这种方式,您的查询将起作用(但每个壁纸中的类别将重复)


或者做这个简单的技巧(如果类别的数量不是太高):

//Get all the ids of the published categories:
$categories = $this->createQueryBuilder('ApplicationDefaultBundle:Category')
            ->field('published')->equals(true)
            ->getQuery()
            ->execute()
$categoriesIds = array();
foreach($categories as $c) {
    $categoriesIds[] = $c->getId();
}

//Get the wallpapers for that categories:
$wallpapers = $this->createQueryBuilder('ApplicationDefaultBundle:Wallpaper')
            ->field('categories.$id')->in($categories)
            ->getQuery()
            ->execute()

如果发布的类别只有100-200,这个技巧就可以了。