You are browsing a version that is no longer maintained.

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 $id; /** @String */ private $title; /** @String */ private $body; /** @EmbedMany(targetDocument="Comment") */ private $comments = array(); // ... } /** @EmbeddedDocument */ class Comment { /** @String */ private $by; /** @String */ private $text; /** @EmbedMany(targetDocument="Comment") */ private $replies = array(); // ... }
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

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

1<?php $post = $dm->createQueryBuilder('BlogPost') ->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 $id; /** @String */ private $name; /** * @ReferenceOne(targetDocument="Category") * @Index */ private $parent; // ... }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Query for children by a specific parent id:

1<?php $children = $dm->createQueryBuilder('Category') ->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 $id; /** @String */ private $name; /** * @ReferenceMany(targetDocument="Category") * @Index */ private $children = array(); // ... }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Query for immediate children of a category:

1<?php $category = $dm->createQueryBuilder('Category') ->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') ->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 { /** @String */ private $name; // ... } /** @Document */ class Category extends BaseCategory { /** @Id */ private $id; /** * @ReferenceMany(targetDocument="Category") * @Index */ private $ancestors = array(); /** * @ReferenceOne(targetDocument="Category") * @Index */ private $parent; // ... } /** @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
35
36

Query for all descendants of a category:

1<?php $categories = $dm->createQueryBuilder('Category') ->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') ->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 $id; /** @String */ private $name; /** @String */ private $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') ->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') ->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.