Come si può usare Doctrine ODM per creare un riferimento bi-direzionale one-to-one che carichi pigri mentre si utilizza un campo diverso da quello principale per il riferimento?Doctrine ODM OneToOne Riferimento bidirezionale utilizzando repositoryMethod
Ho due raccolte in MongoDB con documenti, articolo e articoloMetaData. Per ogni documento di articolo, c'è un ArticleMetaData e viceversa. (Una relazione bidirezionale OneToOne.) Per motivi ereditari, i due tipi di documento devono essere in raccolte separate. Entrambe le collezioni sono aggiornate da sistemi esterni che non hanno alcuna conoscenza degli ID Mongo. Tuttavia contengono un "codice di gruppo" di campo condiviso che può essere utilizzato per abbinare l'articolo giusto ai suoi metadati.
Provo a configurare Doctrine in modo tale da ottenere i metadati per un oggetto articolo e un articolo dal suo oggetto metadati, ma voglio mantenerli pigri. (Non c'è bisogno di interrogare per l'altra estremità quando io non ne ho bisogno.)
Le mappature apparire come segue:
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
E i metodi di repository di cui sopra:
// 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;
}
Tutto sembra funzionare abbastanza bene. Posso interrogare un Articolo o ArticoloMetaData e ottenere l'altro lato, solo il il problema è: non sembra il carico pigro. Quando ho query per un articolo:
$article = $documentManager
->getRepository('FooBarBundle:Article')
->findOneBy(['groupcode' => 123]);
Un sacco di domande vengono eseguite:
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":[]}
Che cosa sto facendo di sbagliato? C'è un modo per portare a termine un riferimento bidirezionale bidirezionale con i vincoli precedenti?
Edit:
Dopo aver letto la risposta di Rob Holmes' ho tolto un test nei metodi repository che potrebbero aver causato il problema. Sfortunatamente il problema rimane e ci sono ancora 3 query in esecuzione dove uno (o due al massimo) è sufficiente.
Grazie per il suggerimento. Credo che tu abbia ragione nel dire che una tale chiamata è sbagliata. Sfortunatamente, in pratica, non fa alcuna differenza. Ho comunque aggiornato il mio post con i tuoi miglioramenti. – Xatoo