I have the following Documents:
User
document.Site
documentEach user has an array of embedded documents inside, each representing an item he follows - a site, a twitter account - with the option to mark specific categories he's interested in. Each embedded document has a reference to the third document - the Site
document (or Twitter
document, etc..).
The question is - using the MongoDB ODM, how can I get the documents of all the users that chose to follow a given site, using the id of that site ?
(see below (after the files) how it is done in the mongodb shell)
User.php
<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\Document
*/
class User {
/**
* @ODM\Id
* @var string
*/
protected $id;
/**
* @ODM\EmbedMany(
* discriminatorMap={
* "site"="SiteFollow",
* "twitter"="TwitterFollow",
* }
* )
* @var ArrayCollection;
*/
protected $follows;
}
SiteFollow.php
<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\EmbeddedDocument
*/
class SiteFollow {
/**
* @ODM\Collection
* @var array
*/
protected $interestingCategories;
/**
* @ODM\ReferenceOne(targetDocument="Site", simple=true)
* @var Site
*/
protected $siteItem;
}
Site.php
<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\Document
*/
class Site {
/**
* @ODM\Id
* @var string
*/
protected $id;
/**
* @ODM\String
* @var string
*/
protected $name;
/**
* @ODM\String
* @var string
*/
protected $url;
}
An example for a user document in the mongo shell:
db.User.findOne()
{
"_id": ObjectId("123"),
"follows": [
{
"interestingCategories": [
"PHP"
]
"siteItem" : ObjectId("OBJECT_ID_OF_SITE_DOCUMENT"),
"_doctrine_class_name" : "site"
}
]
}
Mongo shell command for getting all the users that are following a specific site:
db.User.find({"follows.siteItem": ObjectId("OBJECT_ID_OF_SITE_DOCUMENT")})
Accessing embedded/nested documents – In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks.
Use the Array Index to Query for a Field in the Embedded Document. Using dot notation, you can specify query conditions for field in a document at a particular index or position of the array. The array uses zero-based indexing. When querying using dot notation, the field and index must be inside quotation marks.
MongoDB provides you a cool feature which is known as Embedded or Nested Document. Embedded document or nested documents are those types of documents which contain a document inside another document.
An embedded, or nested, MongoDB Document is a normal document that's nested inside another document within a MongoDB collection. Embedded documents are particularly useful when a one-to-many relationship exists between documents.
I found that answer provided by Madarco sometimes doesn't work properly. If you are querying for the $id
field of the reference field in embedded document you may need to pass MongoId
object to the equals()
method. So in this case it would be:
$repo = $odm->getRepository('User');
$repo->createQueryBuilder()
->field('follows.siteItem.$id')
->equals(new \MongoId($siteId))
->getQuery()
->execute();
Just query for the $id field of the DbRef field siteItem
in the SiteFollow document (which is in an embedded collection in the User document):
$repo = $odm->getRepository("User");
$repo->createQueryBuilder()
->field("follows.siteItem.$id")
->equals($siteId)
->getQuery()
->execute();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With