0

I am using Symfony 2.1 and Doctrine - MongoDBBundle.

I have three documents. The first is a company, which I call "Institution". The second are contacts inside the institution, and the third are the talks the user had with the contact.

Contact and Exchange are embedded into Institution, which is true in real world. This is not a problem.

But a Contact is referenced into an Exchange document. This seem to be more complicated with doctrine2...

At first, I would like to build a form which suggest (in a "option" field, which is Native Choices field or Document field in Symfony 2.1) only the contact embedded in the Institution which is currently "edited".

How to do this ?

I tryed to used data transformers. But this lead to another problem: if I have the Contact object, how can I retrieve the parent "Institution" object ?

Is this possible with a MongoDB native query ? Or with query builder ?

This is my YAML mapping:

For Institution:

SOFFT\ContactBundle\Document\Institution:
  type: document
  fields:
    id:
      id: true
      type: id
# ...
  embedMany:
    contacts:
      targetDocument: Contact
    exchange:
      targetDocument: Exchange

for Contact:

SOFFT\ContactBundle\Document\Contact:
  type: embeddedDocument
  fields:
    id:
      id: true
#...

for Exchange:

SOFFT\ContactBundle\Document\Exchange:
  type: embeddedDocument
  fields:
    id:
      id: true
#...
  referenceOne:
    contact:
      targetDocument: Contact
Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
Julien Fastré
  • 1,008
  • 13
  • 20

1 Answers1

1

ODM expects that reference relationships target documents, not embedded documents. Although you can certainly store ObjectId's within embedded documents, ODM would not know how to resolve the reference, primarily because:

  • Contact has no repository class of its own
  • Querying the Institution collection with a Contact ObjectId wouldn't yield the correct result
  • There is no common interface for querying repositories for embedded ObjectId's (along the lines of how DocumentRepository::find() can take an ObjectId)
  • There's no convention for storing ObjectId's in embedded documents (unlike _id for documents)

To support this, ODM would need to know to query the Institution collection by contacts.id, extract the appropriate Contact from the result, and return that. Ideally, we'd want to use field selection to only obtain the matched embedded document, as described in SERVER-828 (implemented in MongoDB 2.2, which was released today). Would ODM get this functionality in the future, it would likely utilize that feature.

My advice would be to avoid using ODM references in Exchange, and simply store the Contact ObjectId in a field. You could still create a method on Institution's repository to return a list of all ObjectIds among embedded Contact documents, and feed that into a form field. I'm not sure if the DocumentType field from DoctrineMongoDBBundle will be appropriate here, but it's worth a shot (I believe the repository method is configurable).

Lastly, don't forget to specify unique constraints for ObjectId's in your embedded documents.

jmikola
  • 6,892
  • 1
  • 31
  • 61