Permalink
Fetching contributors…
Cannot retrieve contributors at this time
268 lines (184 sloc) 5.53 KB

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.