【问题标题】:Is it possible to disable lazy loading for ODM Doctrine?是否可以禁用 ODM Doctrine 的延迟加载?
【发布时间】:2018-02-15 01:11:33
【问题描述】:

我们正在使用 Silex 和 Doctrine (ODM) 开发 API,我们有对象 Story,它的属性为 images

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

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

    // Other properties and methods
}

我们在存储库中有 get 方法(在 AbstractRepository 中,从中扩展了所有其他存储库)。

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

此方法返回嵌入和引用的对象,但对于 referenceMany,只返回没有数据的 id。

是否可以拒绝延迟加载获取所有文档?

我们找到了一种可能的解决方案——重写方法toArray

【问题讨论】:

  • 当然。您只需将所需的对象添加到 select 子句。很多例子。我承认我没有使用 odm 的查询生成器,但我认为它会起作用。而且我不确定抽象的东西。
  • @Cerad 你能提供一个例子吗,因为我在教义网站ReferenceMany documents will always be handled as collections to allow for lazy loading, regardless of the strategy chosen.找到了
  • 希望可以,但我实际上没有 ODM 测试用例。我认为 ->select('story','image') 可以解决问题,但我实际上并不知道。您可能需要明确加入故事和图像。
  • @Cerad 我使用的是 MongoDb,而不是 SQL,我不能使用 selectjoins

标签: mongodb doctrine-orm doctrine odm


【解决方案1】:

一旦您使用->hydrate(false),您就是在指示 ODM 让开并从 MongoDB 返回原始数据。您将 referenceMany 视为一个 id 数组,因为这是原始表示,不涉及延迟加载。

解决您的问题的最简洁方法是实现StoryRepository,这将触发额外的查询以获取引用的图像:

public function get(string $documentId) : array
{
    $document = $this->createQueryBuilder()
        ->field('id')->equals($documentId)
        ->hydrate(false)
        ->getQuery()
        ->toArray();
    $document['images'] = /* ... */;
    return $document;
}

【讨论】:

  • 是的,我知道这种方法。为什么我不太喜欢它,因为我需要为每个存储库编写它(现在我没有很多,但将来有可能),它们有 ReferenceMany 关系。我认为 Doctrine 提供了解决方案。
  • 它在集合中开箱即用,但您明确告诉它不要通过请求原始数据。
猜你喜欢
  • 2016-02-16
  • 2014-07-20
  • 1970-01-01
  • 2016-11-23
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多