3

I need to have a simple array/collection of strings in my Document, but cannot work out a way to acheive this with Doctrine ODM.

This is an example class/document, with $tags needing to be a simple array of strings:

namespace Acme\ExampleBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/** @MongoDB\Document */
class MyDocument {

    /** @MongoDB\Id */
    protected $id;

    /** @MongoDB\String */
    protected $name;

    /** @MongoDB\EmbedMany */
    protected $tags = array();
}

I've tried different things like @MongoDB\EmbedMany or @MongoDB\EmbedMany(targetDocument="String") I know there is no reason for the last one to work, but I was just trying anything I could think of.

The end result in the Mongo DB as JSON is as simple as this:

{
    "_id": ObjectId("a0afa410caeea70de1000000"),
    "name": "Example Name",
    "tags": ["tag1", "example", "test tag"]
}

What I need help with is, how to have the @MongoDB\EmbedMany annotation to allow me to add only strings into the Collection, which will then look like the above JSON when persisted to the DB.

I hope someone can help, as I'm really stuck with this now. It feels like it should be so simple!

Rob Holmes
  • 3,768
  • 1
  • 16
  • 19
  • If the last one is supposed to be JSON then array would be [ ] not {} - the latter is a single embedded document for which this is not legal syntax. – Asya Kamsky Nov 24 '12 at 15:27
  • Thanks for spotting that Asya. I've edited the question now. – Rob Holmes Nov 24 '12 at 15:41
  • I think you have to define a new model for data validation of sub documents and then attach that model as a embedMany in its parent model, I think. – Sammaye Nov 24 '12 at 23:15

2 Answers2

4

Doctrine MongoDB ODM calls the mapping type for arrays "Hash", which is a little confusing. Your class would look like this:

namespace Acme\ExampleBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/** @MongoDB\Document */
class MyDocument {

    // ...

    /** @MongoDB\Hash */
    protected $tags = array();
}

Flushing to MongoDB should result in an hash stored inside your collection as you described in your question.

For further reference, have a look at the HashType implementation

Sgoettschkes
  • 13,141
  • 5
  • 60
  • 78
  • Yes that's it... Thank you so much! I've been trying to work this out for ages now. I had looked in the annotations folder, but completely missed the Hash type (I think I overlooked it because of the name). – Rob Holmes Nov 25 '12 at 21:18
  • The name is confusing. I have an open PR on the docs trying to solve this issue. – Sgoettschkes Nov 26 '12 at 10:48
  • The naming is stupid and is not even properly documented as far as I can tell. – Vahid Amiri Aug 01 '17 at 11:31
1

also type="collection" works same way as hash

 /**
 * @MongoDB\Field(type="collection")
 */

protected $possibleTags;

/**
 * Set tags
 *
 * @param collection $possibleTags
 * @return $this
 */
public function setPossibleTags($possibleTags)
{
    $this->possibleTags = $possibleTags;
    return $this;
}

/**
 * Get tags
 *
 * @return collection $tags
 */
public function getPossibleTags()
{
    return $this->possibleTags;
}
M.Z.
  • 405
  • 6
  • 17