Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

This example depends on two documents (one League can have many Teams embedded) for EmbedMany and shows us how to use MongoDB as database for our application. For more info visit DoctrineMongoDBBundle, QueryBuilder API, Embedded Mapping, Annotations Reference and Working with Objects.


Controllers.yml


services:
application_nosql.controller.default:
class: Application\NosqlBundle\Controller\DefaultController
arguments:
- @doctrine_mongodb.odm.default_document_manager
- @application_nosql.repository.league

Repositories.yml


services:
application_nosql.repository.league:
class: Application\NosqlBundle\Repository\DefaultRepository
factory: [@doctrine_mongodb, getRepository]
arguments: [Application\NosqlBundle\Document\League]

Controller


For now, I've just kept all in controller below but in real life, you should use service, model and factory classes along with controller to divide the logic.


namespace Application\NosqlBundle\Controller;

use Application\NosqlBundle\Document\League;
use Application\NosqlBundle\Document\Team;
use Application\NosqlBundle\Repository\LeagueRepository;
use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
* @Route("/league", service="application_nosql.controller.default")
*/
class DefaultController extends Controller
{
private $documentManager;
private $leagueRepository;

public function __construct(
DocumentManager $documentManager,
LeagueRepository $leagueRepository
) {
$this->documentManager = $documentManager;
$this->leagueRepository = $leagueRepository;
}

/**
* @param Request $request
*
* @Route("")
* @Method({"POST"})
*
* @return Response
*/
public function createLeagueAction(Request $request)
{
$league = new League();
$league->setName($request->request->get('name'));

$this->documentManager->persist($league);
$this->documentManager->flush();

return new Response('League ID:'.json_encode($league->getId()));
}

/**
* @param Request $request
* @param string $leagueId
*
* @Route("/{leagueId}/team")
* @Method({"POST"})
*
* @return Response
*/
public function createLeagueTeamAction(Request $request, $leagueId)
{
$league = $this->leagueRepository->findOneByProperty('id', $leagueId);
if (!$league instanceof League) {
throw new NotFoundHttpException(
sprintf('League with id [%s] cannot be found.', $leagueId)
);
}

$team = new Team();
$team->setName($request->request->get('name'));

$league->addTeam($team);

$this->documentManager->persist($team);
$this->documentManager->flush();

return new Response('Team ID:'.json_encode($team->getId()));
}
}

League document


namespace Application\NosqlBundle\Document;

use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Date;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Id;

/**
* @MongoDB\Document(collection="league", repositoryClass="Application\NosqlBundle\Repository\LeagueRepository")
* @MongoDB\HasLifecycleCallbacks
*/
class League
{
/**
* @MongoDB\Id
*/
private $id;

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

/**
* @MongoDB\Date
*/
private $createdAt;

/**
* @MongoDB\Date
*/
private $updatedAt;

/**
* @MongoDB\EmbedMany(targetDocument="Team")
*/
private $teams = [];

/**
* @MongoDB\PrePersist
*/
public function onPrePersist()
{
$this->createdAt = new DateTime();
}

/**
* @MongoDB\PreUpdate
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime();
}

public function __construct()
{
$this->teams = new ArrayCollection();
}

/**
* @return id $id
*/
public function getId()
{
return $this->id;
}

/**
* @param string $name
*
* @return self
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* @return string $name
*/
public function getName()
{
return $this->name;
}

/**
* @return date $createdAt
*/
public function getCreatedAt()
{
return $this->createdAt;
}

/**
* @return date $updatedAt
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}

/**
* @param Team $team
*/
public function addTeam(Team $team)
{
$this->teams[] = $team;
}

/**
* @param Team $team
*/
public function removeTeam(Team $team)
{
$this->teams->removeElement($team);
}

/**
* @return Collection $teams
*/
public function getTeams()
{
return $this->teams;
}
}

Team document


namespace Application\NosqlBundle\Document;

use DateTime;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Date;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Id;

/**
* @MongoDB\EmbeddedDocument
* @MongoDB\HasLifecycleCallbacks
*/
class Team
{
/**
* @MongoDB\Id
*/
private $id;

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

/**
* @MongoDB\Date
*/
private $createdAt;

/**
* @MongoDB\Date
*/
private $updatedAt;

/**
* @MongoDB\PrePersist
*/
public function onPrePersist()
{
$this->createdAt = new DateTime();
}

/**
* @MongoDB\PreUpdate
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime();
}

/**
* @return id $id
*/
public function getId()
{
return $this->id;
}

/**
* @param string $name
*
* @return self
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* @return string $name
*/
public function getName()
{
return $this->name;
}

/**
* @return date $createdAt
*/
public function getCreatedAt()
{
return $this->createdAt;
}

/**
* @return date $updatedAt
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}

League repository


namespace Application\NosqlBundle\Repository;

use Doctrine\ODM\MongoDB\DocumentRepository;

class LeagueRepository extends DocumentRepository
{
/**
* @param string $field
* @param string $data
*
* @return array|null|object
*/
public function findOneByProperty($field, $data)
{
return
$this->createQueryBuilder('League')
->field($field)->equals($data)
->getQuery()
->getSingleResult();
}
}

League database


db.getCollection('league').find({})
/* 1 */
{
"_id" : ObjectId("564fa07add576ebcf90041ac"),
"name" : "Super Lig",
"createdAt" : ISODate("2015-11-20T22:36:42.000Z")
}

/* 2 */
{
"_id" : ObjectId("564fa081dd576ebbf90041ad"),
"name" : "Premiership",
"createdAt" : ISODate("2015-11-20T22:36:49.000Z"),
"updatedAt" : ISODate("2015-11-20T22:37:33.000Z"),
"teams" : [
{
"_id" : ObjectId("564fa0a6dd576ef2f80041ad"),
"name" : "Arsenal",
"createdAt" : ISODate("2015-11-20T22:37:26.000Z")
},
{
"_id" : ObjectId("564fa0addd576ebaf90041ad"),
"name" : "Liverpool",
"createdAt" : ISODate("2015-11-20T22:37:33.000Z")
}
]
}

Usage


Create league


POST /nosql/league
{
"name": "Super Lig"
}
{
"name": "Premiership"
}

Create team


POST /nosql/league/564fa081dd576ebbf90041ad/team
{
"name": "Arsenal"
}
{
"name": "Liverpool"
}