You are browsing a version that has not yet been released.

Trees

MongoDB lends itself quite well to storing hierarchical data. This chapter will demonstrate some examples!

Full Tree in Single Document

1<?php #[Document] class BlogPost { #[Id] private string $id; #[Field(type: 'string')] private string $title; #[Field(type: 'string')] private string $body; /** @var Collection<Comment> */ #[EmbedMany(targetDocument: Comment::class)] private Collection $comments; // ... } #[EmbeddedDocument] class Comment { #[Field(type: 'string')] private string $by; #[Field(type: 'string')] private string $text; /** @var Collection<Comment> */ #[EmbedMany(targetDocument: Comment::class)] private Collection $replies; // ... }
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
30
31
32
33
34
35
36

Retrieve a blog post and only select the first 10 comments:

1<?php $post = $dm->createQueryBuilder(BlogPost::class) ->selectSlice('replies', 0, 10) ->getQuery() ->getSingleResult(); $replies = $post->getReplies();
2
3
4
5
6
7
8

You can read more about this pattern on the MongoDB documentation page Trees in MongoDB in the Full Tree in Single Document section.

Parent Reference

1<?php #[Document] class Category { #[Id] private string $id; #[Field(type: 'string')] private string $name; #[ReferenceOne(targetDocument: Category::class)] #[Index] private ?Category $parent = null; // ... }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Query for children by a specific parent id:

1<?php $children = $dm->createQueryBuilder(Category::class) ->field('parent.id')->equals('theid') ->getQuery() ->execute();
2
3
4
5
6

You can read more about this pattern on the MongoDB documentation page Trees in MongoDB in the Parent Links section.

Child Reference

1<?php #[Document] class Category { #[Id] private string $id; #[Field(type: 'string')] private string $name; /** @var Collection<Category> */ #[ReferenceMany(targetDocument: Category::class)] #[Index] private Collection $children; // ... }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Query for immediate children of a category:

1<?php $category = $dm->createQueryBuilder(Category::class) ->field('id')->equals('theid') ->getQuery() ->getSingleResult(); $children = $category->getChildren();
2
3
4
5
6
7
8

Query for immediate parent of a category:

1<?php $parent = $dm->createQueryBuilder(Category::class) ->field('children.id')->equals('theid') ->getQuery() ->getSingleResult();
2
3
4
5
6

You can read more about this pattern on the MongoDB documentation page Trees in MongoDB in the Child Links section.

Array of Ancestors

1<?php #[MappedSuperclass] class BaseCategory { #[Field(type: 'string')] private string $name; // ... } #[Document] class Category extends BaseCategory { #[Id] private string $id; /** @var Collection<Category> */ #[ReferenceMany(targetDocument: Category::class)] #[Index] private Collection $ancestors; /** @var Collection<Category> */ #[ReferenceOne(targetDocument: Category::class)] #[Index] private ?Category $parent = null; // ... } #[EmbeddedDocument] class SubCategory extends BaseCategory { }
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
30
31
32
33
34

Query for all descendants of a category:

1<?php $categories = $dm->createQueryBuilder(Category::class) ->field('ancestors.id')->equals('theid') ->getQuery() ->execute();
2
3
4
5
6

Query for all ancestors of a category:

1<?php $category = $dm->createQuery(Category::class) ->field('id')->equals('theid') ->getQuery() ->getSingleResult(); $ancestors = $category->getAncestors();
2
3
4
5
6
7
8

You can read more about this pattern on the MongoDB documentation page Trees in MongoDB in the Array of Ancestors section.

Materialized Paths

1<?php #[Document] class Category { #[Id] private string $id; #[Field(type: 'string')] private string $name; #[Field(type: 'string')] private string $path; // ... }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Query for the entire tree:

1<?php $categories = $dm->createQuery(Category::class) ->sort('path', 'asc') ->getQuery() ->execute();
2
3
4
5
6

Query for the node 'b' and all its descendants:

1<?php $categories = $dm->createQuery(Category::class) ->field('path')->equals('/^a,b,/') ->getQuery() ->execute();
2
3
4
5

You can read more about this pattern on the MongoDB documentation page Trees in MongoDB in the Materialized Paths (Full Path in Each Node) section.