繁体   English   中英

使用repositoryMethod的Doctrine ODM OneToOne双向参考

[英]Doctrine ODM OneToOne Bi-Directional Reference using repositoryMethod

在使用主键以外的字段进行引用时,如何使用Doctrine ODM创建一对一的双向引用,从而延迟加载?

我在MongoDB中有两个带有文档的集合,即Article和ArticleMetaData。 对于每个Article文档,都有一个ArticleMetaData,反之亦然。 (OneToOne双向关系。)出于遗留原因,这两种文档类型必须位于单独的集合中。 这两个集合都是由不了解Mongo ID的外部系统更新的。 但是,它们确实包含一个共享字段“ groupcode”,可用于将正确的文章与其元数据进行匹配。

我尝试以某种方式配置Doctrine,以便可以从其元数据对象中获取文章对象和文章的元数据,但我希望保持它们的延迟加载。 (不需要时,无需查询另一端。)

映射如下所示:

Foo\BarBundle\Document\Article:
    repositoryClass: Foo\BarBundle\Repository\ArticleRepository
    changeTrackingPolicy: DEFERRED_EXPLICIT
    collection: article
    type: document
    fields:
        id:
            id: true
        groupcode:
            type: int
            index: true
            unique:
                order: asc
        ...
    referenceOne:
        metaData:
            targetDocument: Foo\BarBundle\Document\ArticleMetaData
            mappedBy: groupcode
            repositoryMethod: findOneByArticle

Foo\BarBundle\Document\ArticleMetaData:
    repositoryClass: Foo\BarBundle\Repository\ArticleMetaDataRepository
    changeTrackingPolicy: DEFERRED_EXPLICIT
    collection: article_meta
    fields:
        id:
            id: true
        groupcode:
            type: int
            index: true
            unique:
                order: asc
        ...
    referenceOne:
        article:
            targetDocument: Foo\BarBundle\Document\Article
            mappedBy: groupcode
            repositoryMethod: findOneByMetaData

以及上面提到的存储库方法:

// In the ArticleRepository
public function findOneByMetaData(ArticleMetaData $metadata)
{
    $article = $this
        ->createQueryBuilder()
        ->field('groupcode')->equals($metadata->getGroupcode())
        ->getQuery()
        ->getSingleResult();

    $article->setMetaData($metadata);

    return $article;
}

// In the ArticleMetaDataRepository
public function findOneByArticle(Article $article)
{
    $metaData = $this
        ->createQueryBuilder()
        ->field('groupcode')->equals($article->getGroupcode())
        ->getQuery()
        ->getSingleResult();

    $metaData->setArticle($article);

    return $metaData;
}

一切似乎都很好。 我可以查询Article或ArticleMetaData并获得另一面,唯一的问题是:它似乎没有延迟加载 当我查询文章时:

$article = $documentManager
    ->getRepository('FooBarBundle:Article')
    ->findOneBy(['groupcode' => 123]);

执行了许多查询:

doctrine.INFO: MongoDB query: {"find":true,"query":{"groupcode":123},"fields":[],"db":"development","collection":"article"}
doctrine.INFO: MongoDB query: {"limit":true,"limitNum":1,"query":{"groupcode":123},"fields":[]}
doctrine.INFO: MongoDB query: {"limit":true,"limitNum":null,"query":{"groupcode":123},"fields":[]}
doctrine.INFO: MongoDB query: {"find":true,"query":{"groupcode":123},"fields":[],"db":"development","collection":"article_meta"}
doctrine.INFO: MongoDB query: {"limit":true,"limitNum":1,"query":{"groupcode":123},"fields":[]}
doctrine.INFO: MongoDB query: {"find":true,"query":{"groupcode":123},"fields":[],"db":"development","collection":"article"}
doctrine.INFO: MongoDB query: {"limit":true,"limitNum":1,"query":{"groupcode":123},"fields":[]}

我究竟做错了什么? 有什么办法可以完成具有上述约束的延迟加载一对一双向引用?

编辑:

阅读Rob Holmes的答案后,我在存储库方法中删除了可能导致此问题的测试。 不幸的是,问题仍然存在,并且仍然执行了3个查询,其中一个(或最多两个)查询就足够了。

Doctrine ODM将已经延迟加载引用的文档,而不是为您预取它。

我相信您的问题实际上出在您的存储库方法中...例如,在findOneByMetaData函数中,您要做的第一件事是调用$metadata->getArticle()来执行此操作,这是在要求教义从数据库中加载文章,由于您的repositoryMethod将要再次调用findOneByMetaData 这就是为什么您看到多个查询的原因。

您的findOneByMetaData函数应如下所示:

// In the ArticleRepository
public function findOneByMetaData(ArticleMetaData $metadata)
{
    $article = $this->createQueryBuilder()
        ->field('groupcode')->equals($metadata->getGroupcode())
        ->getQuery()
        ->getSingleResult();

    $article->setMetaData($metadata);

    return $article;
}

Doctrine会检查文章是否已加载,因此无需尝试检查空值。 这同样也适用于您的findOneByArticle函数。

希望这有道理,并可以帮助您解决问题。

这是因为有Logger(loggableCursor),它会在日志文件中重复查询。 例如,您调用... find()-> limit(1)-> getQuery()会记录每个调用,但实际上只有一个查询请求。

更多信息: https : //github.com/doctrine/mongodb-odm/issues/471#issuecomment-63999514

ODM问题: https//github.com/doctrine/mongodb/issues/151

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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