-->

Which mapping type to choose for associative Array

2020-06-09 08:40发布

问题:

I have a simple question about the (by the way really great!) Doctrine ODM.

Assume you have a document like:

/**
 * @Document
 */
class Test
{
    /** @Id */
    public $id;
    /** @WHICHTYPE */
    public $field = array();
}

Now i want to store an associative array like

array("test" => "test1", "anothertest" => "test2", ......);

In the $field property of that class.

No problem for MongoDB, I know, but in Doctrine when I use for example @Collection or simply @Field, only the values are stored (array_values is being used in the mapping driver for collection for example). So the stored value looks like

array("test1", "test2", ....)

Does anyone know which Doctrine-ODM mapping type I should use in order to preserve the key-value pairs in the database?

Thank you in advance,

Andi (greetz from germany)

回答1:

It should be the Hash type:

http://readthedocs.org/docs/doctrine-mongodb-odm/en/latest/reference/annotations-reference.html?highlight=hash#hash



回答2:

For versions before ODM 2.0 @Hash will provide the necessary data type. However after ODM 2.0 @Hash field is being removed. In order to use it we have to use @field with type hash. For further reference [click here][1]



回答3:

I think you're looking for hash data type. Aren't you?

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @Document
 */
class Test
{
    /** @Id */
    public $id;

    /**
     * @MongoDB\Field(type="hash")
    */
    public $field;
}


回答4:

The best answer is using hash type. But if for some reason you wantn't use hash type, you can use EmbeddedDocument feature provided by Doctrine ODM like the documentation says:

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. \MongoDate instead of \DateTime).

So, you need to create EmbeddedDocument EmbeddedExample in AppBundle\Document\EmbeddedExample.php:

<?php

namespace AppBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\EmbeddedDocument()
 */
class EmbeddedExample
{
    /**
     * @MongoDB\Field(type="int")
     */
    protected $some_name;

    // ...
    // getter and setter
}

Then, you can use EmbeddedExample in your Test document. So the Test.php file will be similar to this:

<?php

namespace AppBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
* @MongoDB\Document(repositoryClass="AppBundle\Repository\TestRepository")
*/
class Test
{

    /** @MongoDB\EmbedOne(targetDocument="EmbeddedExample") */
    private $field;

    // ...
}


回答5:

@Array should work. At least an equivalent exists in the ORM (@Column(type="array"))