17/11/2015 - DOCTRINE, MONGODB, SYMFONY
This example depends on two documents (one League
can have many Team
s 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.
services:
application_nosql.controller.default:
class: Application\NosqlBundle\Controller\DefaultController
arguments:
- @doctrine_mongodb.odm.default_document_manager
- @application_nosql.repository.league
services:
application_nosql.repository.league:
class: Application\NosqlBundle\Repository\DefaultRepository
factory: [@doctrine_mongodb, getRepository]
arguments: [Application\NosqlBundle\Document\League]
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()));
}
}
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;
}
}
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;
}
}
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();
}
}
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")
}
]
}
POST /nosql/league
{
"name": "Super Lig"
}
{
"name": "Premiership"
}
POST /nosql/league/564fa081dd576ebbf90041ad/team
{
"name": "Arsenal"
}
{
"name": "Liverpool"
}