Complex References
Sometimes you may want to access related documents using custom criteria or from the inverse side of a relationship.
You can create an immutable reference to one or many documents and specify
how that reference is to be loaded. The reference is immutable in that it is
defined only in the mapping, unlike a typical reference where a DBRef
or
identifier (see Storing References) is stored on the document itself.
The following options may be used for one and many reference mappings:
criteria
- Query criteria to apply to the cursor.repositoryMethod
- The repository method used to create the cursor.sort
- Sort criteria for the cursor.skip
- Skip offset to apply to the cursor.limit
- Limit to apply to the cursor.
Basic Example
In the following example, $comments
will refer to all Comments for the
BlogPost and $last5Comments
will refer to only the last five Comments. The
mappedBy
field is used to determine which Comment field should be used for
querying by the BlogPost's ID.
1 <?php
#[Document]
class BlogPost
{
// ...
/** @var Collection<Comment> */
#[ReferenceMany(targetDocument: Comment::class, mappedBy: 'blogPost')]
private Collection $comments;
/** @var Collection<Comment> */
#[ReferenceMany(
targetDocument: Comment::class,
mappedBy: 'blogPost',
sort: ['date' => 'desc'],
limit: 5,
)]
private Collection $last5Comments;
}
#[Document]
class Comment
{
// ...
#[ReferenceOne(targetDocument: BlogPost::class, inversedBy: 'comments')]
private BlogPost $blogPost;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
You can also use mappedBy
for referencing a single document, as in the
following example:
criteria
Example
Use criteria
to further match referenced documents. In the following
example, $commentsByAdmin
will refer only comments created by
administrators:
repositoryMethod
Example
Alternatively, you can use repositoryMethod
to specify a custom method to
call on the Comment repository class to populate the reference.
The Comment
class will need to have a custom repository class configured:
Lastly, the CommentRepository
class will need a findSomeComments()
method which shall return Doctrine\ODM\MongoDB\Iterator\Iterator
. When this method
is called to populate the reference, Doctrine will provide the Blogpost instance
(i.e. owning document) as the first argument:
1 <?php
use Doctrine\ODM\MongoDB\Iterator\Iterator;
class CommentRepository extends \Doctrine\ODM\MongoDB\DocumentRepository
{
public function findSomeComments(BlogPost $blogPost): Iterator
{
return $this->createQueryBuilder()
->field('blogPost')->references($blogPost)
->getQuery()->execute();
}
}
2
3
4
5
6
7
8
9
10
11
12
13