简体   繁体   中英

Symfony 2 Doctrine ODM with reference

So I have two following documents:

Wallpapers

/**
 * @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();
    }
}

Categories:

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

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

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

And I need select all wallpapers which contain only published categories... I tried many solutions, which I found by Google search. But still not found solution for my problem...

Here my query:

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

But it doesn't work:(

Any suggestions?

On a relational DB you'll do that with a Join, however in mongodb you can either:


de-normalize your referenced category in your Wallpaper document:

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

(notice the EmbedMany)

In this way your query will work (but the categories will be duplicated inside each Wallpaper)


Or do this simple trick (if the number of categories isn't too high):

//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()

If the published categories are only 100-200 this trick is ok.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM