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
<?php#[Document]class BlogPost{ #[Id] private string $id; #[Field(type: 'string')] private string $title; #[Field(type: 'string')] private string $body; /** @var Collection<int, 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<int, Comment> */ #[EmbedMany(targetDocument: Comment::class)] private Collection $replies; // ...}
Retrieve a blog post and only select the first 10 comments:
<?php$post = $dm->createQueryBuilder(BlogPost::class) ->selectSlice('replies', 0, 10) ->getQuery() ->getSingleResult();$replies = $post->getReplies();
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
<?php#[Document]class Category{ #[Id] private string $id; #[Field(type: 'string')] private string $name; #[ReferenceOne(targetDocument: Category::class)] #[Index] private ?Category $parent = null; // ...}
Query for children by a specific parent id:
<?php$children = $dm->createQueryBuilder(Category::class) ->field('parent.id')->equals('theid') ->getQuery() ->execute();
You can read more about this pattern on the MongoDB documentation page "Trees in MongoDB" in the Parent Links section.
Child Reference
<?php#[Document]class Category{ #[Id] private string $id; #[Field(type: 'string')] private string $name; /** @var Collection<int, Category> */ #[ReferenceMany(targetDocument: Category::class)] #[Index] private Collection $children; // ...}
Query for immediate children of a category:
<?php$category = $dm->createQueryBuilder(Category::class) ->field('id')->equals('theid') ->getQuery() ->getSingleResult();$children = $category->getChildren();
Query for immediate parent of a category:
<?php$parent = $dm->createQueryBuilder(Category::class) ->field('children.id')->equals('theid') ->getQuery() ->getSingleResult();
You can read more about this pattern on the MongoDB documentation page "Trees in MongoDB" in the Child Links section.
Array of Ancestors
<?php#[MappedSuperclass]class BaseCategory{ #[Field(type: 'string')] private string $name; // ...}#[Document]class Category extends BaseCategory{ #[Id] private string $id; /** @var Collection<int, Category> */ #[ReferenceMany(targetDocument: Category::class)] #[Index] private Collection $ancestors; /** @var Collection<int, Category> */ #[ReferenceOne(targetDocument: Category::class)] #[Index] private ?Category $parent = null; // ...}#[EmbeddedDocument]class SubCategory extends BaseCategory{}
Query for all descendants of a category:
<?php$categories = $dm->createQueryBuilder(Category::class) ->field('ancestors.id')->equals('theid') ->getQuery() ->execute();
Query for all ancestors of a category:
<?php$category = $dm->createQuery(Category::class) ->field('id')->equals('theid') ->getQuery() ->getSingleResult();$ancestors = $category->getAncestors();
You can read more about this pattern on the MongoDB documentation page "Trees in MongoDB" in the Array of Ancestors section.
Materialized Paths
<?php#[Document]class Category{ #[Id] private string $id; #[Field(type: 'string')] private string $name; #[Field(type: 'string')] private string $path; // ...}
Query for the entire tree:
<?php$categories = $dm->createQuery(Category::class) ->sort('path', 'asc') ->getQuery() ->execute();
Query for the node 'b' and all its descendants:
<?php$categories = $dm->createQuery(Category::class) ->field('path')->equals('/^a,b,/') ->getQuery() ->execute();
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.
