Skip to content

Latest commit

 

History

History
267 lines (184 loc) · 5.49 KB

trees.rst

File metadata and controls

267 lines (184 loc) · 5.49 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::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.

Parent Reference

<?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.

Child Reference

<?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.

Array of Ancestors

<?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.

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::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.