You are browsing a version that is no longer maintained. |
Basic Mapping
This chapter explains the basic mapping of objects and properties. Mapping of references and embedded documents will be covered in the next chapter "Reference Mapping".
Mapping Drivers
Doctrine provides several different ways for specifying object document mapping metadata:
- Docblock Annotations
- Attributes
- XML
- Raw PHP Code
If you're wondering which mapping driver gives the best
performance, the answer is: None. Once the metadata of a class has
been read from the source (annotations or xml) it is stored
in an instance of the
|
Introduction to Docblock Annotations
To be able to use annotations, you will have to install an extra
package called |
You've probably used docblock annotations in some form already,
most likely to provide documentation metadata for a tool like
PHPDocumentor
(@author, @link, ...). Docblock annotations are a
tool to embed metadata inside the documentation section which can
then be processed by some tool. Doctrine generalizes the concept of
docblock annotations so that they can be used for any kind of
metadata and so that it is easy to define new docblock annotations.
In order to allow more involved annotation values and to reduce the
chances of clashes with other docblock annotations, the Doctrine
docblock annotations feature an alternative syntax that is heavily
inspired by the Annotation syntax introduced in Java 5.
The implementation of these enhanced docblock annotations is located in
the doctrine/annotations
package, but in the
Doctrine\Common\Annotations
namespace for backwards compatibility
reasons. Note that doctrine/annotations
is not required by Doctrine
MongoDB ODM, and you will need to require that package if you want to use
annotations. Doctrine MongoDB ODM docblock annotations support namespaces and
nested annotations among other things. The Doctrine MongoDB ODM defines its
own set of docblock annotations for supplying object-relational mapping
metadata.
If you're not comfortable with the concept of docblock annotations, don't worry, as mentioned earlier Doctrine provides XML alternative and you could easily implement your own favorite mechanism for defining ODM metadata. |
Persistent classes
In order to mark a class for object-relational persistence it needs
to be designated as a document. This can be done through the
@Document
marker annotation.
By default, the document will be persisted to a database named
doctrine and a collection with the same name as the class name. In
order to change that, you can use the db
and collection
option as follows:
Now instances of Documents\User
will be persisted into a
collection named users
in the database my_db
.
If you want to omit the db attribute you can configure the default db
to use with the setDefaultDB
method:
Doctrine Mapping Types
A Doctrine Mapping Type defines the mapping between a PHP type and a MongoDB type. You can even write your own custom mapping types.
Here is a quick overview of the built-in mapping types:
bin
bin_bytearray
bin_custom
bin_func
bin_md5
bin_uuid
bool
collection
custom_id
date
date_immutable
decimal128
file
float
hash
id
int
key
object_id
raw
string
timestamp
You can read more about the available MongoDB types on php.net.
The Doctrine mapping types are used to convert the local PHP types to the MongoDB types
when persisting so that your domain is not bound to MongoDB-specific types. For example a
DateTime instance may be converted to |
Generally, the name of each built-in mapping type hints as to how the value will be converted. This list explains some of the less obvious mapping types:
bin
: string to MongoDBBSONBinary instance with a "generic" type (default)bin_bytearray
: string to MongoDBBSONBinary instance with a "byte array" typebin_custom
: string to MongoDBBSONBinary instance with a "custom" typebin_func
: string to MongoDBBSONBinary instance with a "function" typebin_md5
: string to MongoDBBSONBinary instance with a "md5" typebin_uuid
: string to MongoDBBSONBinary instance with a "uuid" typecollection
: numerically indexed array to MongoDB arraydate
: DateTime toMongoDB\BSON\UTCDateTime
date_immutable
: DateTimeImmutable toMongoDB\BSON\UTCDateTime
decimal128
: string toMongoDB\BSON\Decimal128
, requiresext-bcmath
hash
: associative array to MongoDB objectid
: string to ObjectId by default, but other formats are possibletimestamp
: string toMongoDB\BSON\Timestamp
raw
: any type
If you are using the hash type, values within the associative array are
passed to MongoDB directly, without being prepared. Only formats suitable for
the Mongo driver should be used. If your hash contains values which are not
suitable you should either use an embedded document or use formats provided
by the MongoDB driver (e.g. |
PHP Types Mapping
Doctrine will skip type autoconfiguration if settings are provided explicitly. |
Since version 2.4 Doctrine can determine usable defaults from property types
on document classes. Doctrine will map PHP types to type
attribute as
follows:
DateTime
:date
DateTimeImmutable
:date_immutable
array
:hash
bool
:bool
float
:float
int
:int
string
:string
Doctrine can also autoconfigure any backed enum
it encounters: type
will be set to string
or int
, depending on the enum's backing type,
and enumType
to the enum's FQCN.
Nullable type does not imply |
Additionally Doctrine can determine collectionClass
for ReferenceMany
and
EmbedMany
collections from property's type.
Property Mapping
After a class has been marked as a document it can specify mappings for its instance fields. Here we will only look at simple fields that hold scalar values like strings, numbers, etc. References to other objects and embedded objects are covered in the chapter "Reference Mapping".
Identifiers
Every document class needs an identifier. You designate the field
that serves as the identifier with the @Id
marker annotation.
Here is an example:
You can configure custom ID strategies if you don't want to use the default object ID. The available strategies are:
AUTO
- Uses the native generated ObjectId.ALNUM
- Generates an alpha-numeric string (based on an incrementing value).CUSTOM
- Defers generation to a AbstractIdGenerator implementation specified in theclass
option.INCREMENT
- Uses another collection to auto increment an integer identifier.UUID
- Generates a UUID identifier.NONE
- Do not generate any identifier. ID must be manually set.
Here is an example how to manually set a string identifier for your documents:
When using the NONE
strategy you will have to explicitly set an id before persisting the document:
Now you can retrieve the document later:
You can define your own ID generator by extending the
Doctrine\ODM\MongoDB\Id\AbstractIdGenerator
class and specifying the class
as an option for the CUSTOM
strategy:
Fields
To mark a property for document persistence the @Field
docblock
annotation can be used. This annotation usually requires at least 1
attribute to be set, the type
. The type
attribute specifies
the Doctrine Mapping Type to use for the field. If the type is not
specified, 'string' is used as the default mapping type since it is
the most flexible.
Example:
In that example we mapped the property id
to the field id
using the mapping type id
and the property name
is mapped
to the field name
with the default mapping type string
. As
you can see, by default the mongo field names are assumed to be the
same as the property names. To specify a different name for the
field, you can use the name
attribute of the Field annotation
as follows:
Multiple Document Types in a Collection
You can easily store multiple types of documents in a single collection. This
requires specifying the same collection name, discriminatorField
, and
(optionally) discriminatorMap
mapping options for each class that will share
the collection. Here is an example:
1 <?php
/**
* @Document(collection="my_documents")
* @DiscriminatorField("type")
* @DiscriminatorMap({"article"=Article::class, "album"=Album::class})
*/
class Article
{
// ...
}
/**
* @Document(collection="my_documents")
* @DiscriminatorField("type")
* @DiscriminatorMap({"article"=Article::class, "album"=Album::class})
*/
class Album
{
// ...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
All instances of Article
and Album
will be stored in the
my_documents
collection. You can query for the documents of a particular
class just like you normally would and the results will automatically be limited
based on the discriminator value for that class.
If you wish to query for multiple types of documents from the collection, you may pass an array of document class names when creating a query builder:
The above will return a cursor that will allow you to iterate over all
Article
and Album
documents in the collections.