0

We are developing API with Silex and Doctrine (ODM) and we have object Story, which have property images.

class Story extends AbstractDocument
{
    /** @MongoDB\Id */
    protected $id;

    /**
     * @MongoDB\ReferenceMany(
     *     targetDocument="MyNamespace\Documents\Image",
     *     storeAs="DBRef"
     * )
     */
    protected $images = [];

    // Other properties and methods
}

We have get method in repository (in AbstractRepository, from which extends all other repositories).

public function get(string $documentId) : array
{
    $document = $this->createQueryBuilder()
        ->field('id')->equals($documentId)
        ->hydrate(false)
        ->getQuery()
        ->toArray();
}

This method returns embedded and referenced objects, but for referenceMany returns only ids without data.

Is it possible to deny lazy loading to get all documents ?

One possible solution, which we found - rewrite method toArray.

yAnTar
  • 4,269
  • 9
  • 47
  • 73
  • Sure. You just add the objects you want to the select clause. Plenty of examples. I will admit I have not used the query builder with odm but I assume it will work. And I'm not sure about the abstract stuff. – Cerad Sep 06 '17 at 14:06
  • @Cerad Could you please provide an example, because I found on doctrine site `ReferenceMany documents will always be handled as collections to allow for lazy loading, regardless of the strategy chosen.` – yAnTar Sep 06 '17 at 14:33
  • Wish I could but I don't actually have an ODM test case. I would think that ->select('story','image') would do the trick but I don't actually know. And you might need to explicitly join story and image. – Cerad Sep 06 '17 at 14:54
  • @Cerad I'm using MongoDb, not SQL and I can't use `select` and `joins` – yAnTar Sep 06 '17 at 14:57

1 Answers1

0

As soon as you use ->hydrate(false) you are instructing ODM to get out of your way and return you raw data from MongoDB. You are seeing the referenceMany as an array of ids because that is the raw representation, no lazy loading is involved.

The cleanest way to solve your issue would be implementing StoryRepository which would fire an additional query to get referenced images:

public function get(string $documentId) : array
{
    $document = $this->createQueryBuilder()
        ->field('id')->equals($documentId)
        ->hydrate(false)
        ->getQuery()
        ->toArray();
    $document['images'] = /* ... */;
    return $document;
}
malarzm
  • 2,831
  • 2
  • 15
  • 25
  • Yes, I know about this approach. Why I don't like it well, because I need write it for every repository (now I don't have a lot of it, but in future it's possible), which have ReferenceMany relations. I thought that Doctrine provides solution for that. – yAnTar Sep 07 '17 at 16:47
  • Well it does out of the box with collections, but you're specifically telling it to not by requesting raw data. – malarzm Sep 08 '17 at 06:50