MongoDB lends itself quite well to storing hierarchical data. This chapter will demonstrate some examples!
<?php
/** @Document */
class BlogPost
{
/** @Id */
private $id;
/** @Field(type="string") */
private $title;
/** @Field(type="string") */
private $body;
/** @EmbedMany(targetDocument=Comment::class) */
private $comments = [];
// ...
}
/** @EmbeddedDocument */
class Comment
{
/** @Field(type="string") */
private $by;
/** @Field(type="string") */
private $text;
/** @EmbedMany(targetDocument=Comment::class) */
private $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.
<?php
/** @Document */
class Category
{
/** @Id */
private $id;
/** @Field(type="string") */
private $name;
/**
* @ReferenceOne(targetDocument=Category::class)
* @Index
*/
private $parent;
// ...
}
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.
<?php
/** @Document */
class Category
{
/** @Id */
private $id;
/** @Field(type="string") */
private $name;
/**
* @ReferenceMany(targetDocument=Category::class)
* @Index
*/
private $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.
<?php
/** @MappedSuperclass */
class BaseCategory
{
/** @Field(type="string") */
private $name;
// ...
}
/** @Document */
class Category extends BaseCategory
{
/** @Id */
private $id;
/**
* @ReferenceMany(targetDocument=Category::class)
* @Index
*/
private $ancestors = [];
/**
* @ReferenceOne(targetDocument=Category::class)
* @Index
*/
private $parent;
// ...
}
/** @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.
<?php
/** @Document */
class Category
{
/** @Id */
private $id;
/** @Field(type="string") */
private $name;
/** @Field(type="string") */
private $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.