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:
Php
Xml
1 <?php
namespace Documents ;
abstract class BaseDocument
{
}
2
3
4
5
6
7
8
1 <?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<mapped-superclass name ="Documents\BaseDocument" >
</mapped-superclass >
</doctrine-mongo-mapping >
2
3
4
5
6
7
8
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:
Php
Xml
1 <?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Person" inheritance-type ="SINGLE_COLLECTION" >
<discriminator-field name ="type" />
<discriminator-map >
<discriminator-mapping value ="person" class ="Person" />
<discriminator-mapping value ="employee" class ="Employee" />
</discriminator-map >
</document >
</doctrine-mongo-mapping >
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Employee" >
</document >
</doctrine-mongo-mapping >
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:
1 <?php
$employee = new Employee();
$dm->persist($employee);
$dm->flush();
$employee = $dm->find(Person::class, $employee->getId());
2
3
4
5
6
7
8
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:
Php
Xml
1 <?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Person" inheritance-type ="SINGLE_COLLECTION" >
<discriminator-field name ="type" />
<discriminator-map >
<discriminator-mapping value ="person" class ="Person" />
<discriminator-mapping value ="employee" class ="Employee" />
</discriminator-map >
<default-discriminator-value value ="person" />
</document >
</doctrine-mongo-mapping >
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Employee" >
</document >
</doctrine-mongo-mapping >
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
With collection per class inheritance, each document is stored in its own
collection and contains all inherited fields:
Php
Xml
1 <?php
namespace Documents ;
class Person
{
}
class Employee extends Person
{
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1 <?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Person" inheritance-type ="COLLECTION_PER_CLASS" >
</document >
</doctrine-mongo-mapping >
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd" >
<document name ="Documents\Employee" >
</document >
</doctrine-mongo-mapping >
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
A discriminator is not needed with this type of inheritance since the data is
separated in different collections.