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 $id;
/** @Field(type="string") */
private $title;
/** @Field(type="string") */
private $body;
/** @EmbedMany(targetDocument="Comment") */
private $comments = array();
// ...
}
/** @EmbeddedDocument */
class Comment
{
/** @Field(type="string") */
private $by;
/** @Field(type="string") */
private $text;
/** @EmbedMany(targetDocument="Comment") */
private $replies = array();
// ...
}
Retrieve a blog post and only select the first 10 comments:
<?php
$post = $dm->createQueryBuilder('BlogPost')
->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 $id;
/** @Field(type="string") */
private $name;
/**
* @ReferenceOne(targetDocument="Category")
* @Index
*/
private $parent;
// ...
}
Query for children by a specific parent id:
<?php
$children = $dm->createQueryBuilder('Category')
->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 $id;
/** @Field(type="string") */
private $name;
/**
* @ReferenceMany(targetDocument="Category")
* @Index
*/
private $children = array();
// ...
}
Query for immediate children of a category:
<?php
$category = $dm->createQueryBuilder('Category')
->field('id')->equals('theid')
->getQuery()
->getSingleResult();
$children = $category->getChildren();
Query for immediate parent of a category:
<?php
$parent = $dm->createQueryBuilder('Category')
->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 $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
{
}
Query for all descendants of a category:
<?php
$categories = $dm->createQueryBuilder('Category')
->field('ancestors.id')->equals('theid')
->getQuery()
->execute();
Query for all ancestors of a category:
<?php
$category = $dm->createQuery('Category')
->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 $id;
/** @Field(type="string") */
private $name;
/** @Field(type="string") */
private $path;
// ...
}
Query for the entire tree:
<?php
$categories = $dm->createQuery('Category')
->sort('path', 'asc')
->getQuery()
->execute();
Query for the node 'b' and all its descendants:
<?php
$categories = $dm->createQuery('Category')
->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.