You are browsing a version that is no longer maintained. |
Inheritance Mapping
Doctrine currently offers two supported methods of inheritance: single collection and collection per class inheritance.
Mapped Superclasses
A mapped superclass is an abstract or concrete class that provides mapping information for its subclasses, but is not itself a document. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple document classes.
Just like non-mapped classes, mapped superclasses may appear in the middle of an otherwise mapped inheritance hierarchy (through single collection or collection per class) inheritance.
A mapped superclass cannot be a document and is not queryable. |
Example:
Single Collection Inheritance
In single collection inheritance, each document is stored in a single collection and a discriminator field is used to distinguish one document type from another.
Simple example:
1 <?php
namespace Documents;
/**
* @Document
* @InheritanceType("SINGLE_COLLECTION")
* @DiscriminatorField("type")
* @DiscriminatorMap({"person"=Person::class, "employee"=Employee::class})
*/
class Person
{
// ...
}
/**
* @Document
*/
class Employee extends Person
{
// ...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
The discriminator value allows Doctrine to infer the class name to instantiate when hydrating a document. If a discriminator map is used, the discriminator value will be used to look up the class name in the map.
Now, if we query for a Person and its discriminator value is employee
, we
would get an Employee instance back:
Even though we queried for a Person, Doctrine will know to return an Employee instance because of the discriminator map!
If your document structure has changed and you've added discriminators after already having a bunch of documents, you can specify a default value for the discriminator field:
1 <?php
namespace Documents;
/**
* @Document
* @InheritanceType("SINGLE_COLLECTION")
* @DiscriminatorField("type")
* @DiscriminatorMap({"person"=Person::class, "employee"=Employee::class})
* @DefaultDiscriminatorValue("person")
*/
class Person
{
// ...
}
/**
* @Document
*/
class Employee extends Person
{
// ...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Collection Per Class Inheritance
With collection per class inheritance, each document is stored in its own collection and contains all inherited fields:
A discriminator is not needed with this type of inheritance since the data is separated in different collections.