I have this document Scheme:
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(collection="users") *
*/
class Markers
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\Float
*/
protected $lat;
/**
* #MongoDB\Float
*/
protected $lng;
/**
* #MongoDB\String
*/
protected $title;
}
What I want is having index on $title field and $lat and $lng
how do you suggest I should work this out ?
Do I have to tell the document that these fields are indexes or , running the command in Mongo shell is sufficient ?
Thanks !
You can define indexes in Mongo shell and make it independent from code implementation. Your database would be accessible from different systems and mantain consistency in its administration.
¿Have you considered the use of geospacial indexes for lng and lat?
Related
I'm converting a project to Doctrine 2.4 and the used database there is PostgreSQL.
I was wondering if it's possible to tell Doctrine to create the columns of the table(entity) in a particular order?
The table I'm currently converting has a lot of columns and some of them are relations to other tables. When the table is created, the first columns would be the primary keys, followed by foreign keys and at the end - everything else.
Here is an example code:
/**
* #Entity
* #Table(name="receipts")
*/
class Receipt {
/**
* #var
* #Id
* #GeneratedValue(strategy="IDENTITY")
* #Column(name="receipt_id", type="integer")
*/
private $receipt_id;
/**
* #var
* #Column(name="created_date", type="date", nullable=false)
*/
private $created_date;
/**
* #var
* #Column(name="updated_date", type="date", nullable=true)
*/
private $updated_date;
/**
* #var
* #Column(name="invoice_number", type="string", nullable=true)
*/
private $invoice_number;
/**
* #var
* #Column(name="invoice_date", type="date", nullable=true)
*/
private $invoice_date;
/**
* #var
* #Column(name="invoice_link", type="text", nullable=true)
*/
private $invoice_link;
/**
* #var
* #ManyToOne(targetEntity="models\Receipts\Invoice\Type")
* #JoinColumn(name="invoice_type_id", referencedColumnName="invoice_type_id")
*/
private $invoiceType;
/**
* #var
* #ManyToOne(targetEntity="models\Payments\Method")
* #JoinColumn(name="invoice_payment_method_id", referencedColumnName="payment_method_id")
*/
private $invoicePaymentMethod;
/**
* #var
* #ManyToOne(targetEntity="models\Payments\Type")
* #JoinColumn(name="invoice_payment_type_id", referencedColumnName="payment_type_id")
*/
private $invoicePaymentType;
public function __construct(){
$this->created_date = new \Date_Time();
$this->updated_date = new \Date_Time();
}
?>
The code above will look like this in PHPPgAdmin:
And this is how I would like the columns to appear:
Of course, everything is working fine. It's just the people working on the project with me (including I) are used to seeing the tables & columns ordered in a concrete way so that we could find things fast and easy. Hopefully there is a Doctrine ninja here that could help me with this. I couldn't find anything in the documentation.
I cannot find in doctrine manual how to do a very simple query. I don't know how to manage the equivalent of SQL "JOIN ..." with MongoDb.
abstract class Topic
{
/**
* #MongoDB\Id
*/
protected $id;
}
abstract class Message
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\Date
*/
protected $date;
/**
* #MongoDB\ReferenceOne(targetDocument="Topic")
*/
protected $topic;
}
abstract class User
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\ReferenceMany(targetDocument="Message")
*/
protected $messages;
}
I have a User id and a Topic id.
I want :
1) Find the most recent message from the user
2) Find the most recent message about the topic from the user
$dm->find('User', $id)->getMessages() gives me a "PersistentCollection"
$dm->find('User', $id)->getMessages()->getValues() gives me the array of the messages, but then I have to use PHP loops, i'm sure there is a way to create a query to do that ...
Am I supposed to use map or reduce ?
Can someone help me ? Thanks !
First, you'll have to fix your database schema:
A Message can belong to more than one User?
Usually a Message can have only an author, so I'll change the Message Document to store the author User id:
class Message
{
/**
* #MongoDB\ReferenceOne(targetDocument="User")
*/
protected $author;
//Othe methods...
}
Then to find the most recent Message from user:
class User {
/**
* #ReferenceOne(
* targetDocument="Message",
* mappedBy="author",
* sort={"date"="desc"}
* )
*/
protected $lastMessage;
//Other methods...
}
And to find the most recent message about a topic:
class User {
/**
* #ReferenceOne(
* targetDocument="Message",
* mappedBy="author",
* criteria={"topic" : "sport"}
* sort={"date"="desc"}
* )
*/
protected $lastMessageAboutSport
//Other methods...
}
More info on: Doctrine ODM Complex References Guide
I need help. Here is the situation. I am using Symfony2 + FOSRestBundle, I created my Entity-Classes to store my data in MySQL via Doctrine. I also wrote all the Controllers to get the data and directly translate it to my database. That works fine.
namespace Stat\ContentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="agegroups")
*/
class Table
{
* #ORM\Column(name="id", type="smallint")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(name="description", type="string", length=50)
* #Type("string")
*/
protected $description;
Now I do want to use the same Entity declaration and extend it with some more information for usage with MongoDB. I want to store my data in MySQL and additionally in MongoDB. To reuse the code with the mongodb-odm-bundle I have to use the namespace Document - and that's just the beginning of the problems. If I would want to reuse my Controllers I would have to rewrite that code for MongoDB as well.
namespace Stat\ContentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document
* #ORM\Entity
* #ORM\Table(name="agegroups")
*/
class Table
{
* #ORM\Column(name="id", type="smallint")
* #ORM\Id
* #MongoDB\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(name="description", type="string", length=50)
* #MongoDB\String
* #Type("string")
*/
protected $description;
/**
* #ORM\Column(name="mySqlOnly", type="string", length=50)
* #Type("string")
*/
protected $mySqlOnly;
/**
* #MongoDB\String
*/
protected $mongoDbOnly;
Is there an easy way to use a Doctrine-database schema for both document-based and relational databases?
Maybe this helps:
Blending the ORM and MongoDB ODM
It is quote easy to use a database nybrid with Doctrine2 since you have an entity- plus an documentmanager.
I'm try to serialize a MongoDB document with embedded documents within Symfony 2.1. I am using the JMSserializer and Mongodb-odm bundles.
I have the following Documents entities.
// Blog
namespace App\DocumentBundle\Document;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\SerializerBundle\Annotation\Type;
/**
* #MongoDB\Document(repositoryClass="App\DocumentBundle\Repository\BlogRepository")
*/
class Blog {
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
* #Assert\NotBlank()
*/
protected $title;
/**
* #MongoDB\string
* #Assert\NotBlank()
*/
protected $blog;
/**
* #MongoDB\EmbedMany(targetDocument="Tag")
*/
private $tags;
/**
* #MongoDB\Timestamp
*/
protected $created;
/**
* #MongoDB\Timestamp
*/
protected $updated;
}
and
// Tag
namespace App\DocumentBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\EmbeddedDocument
*/
class Tag {
/**
* #MongoDB\String
*/
protected $name;
}
An ArrayCollection type is generated for the tag attribute, but the JMSSerializer bundle doesn't like it. If I change the tag to #MongoDB\String and regenerate the Blog document,
then serialization occurs, but not with #MongoDB\EmbedMany(targetDocument="Tag") set.
Do I need to specify some of the JMSSerializer annotated attributes allow embedded document to also be serialized?
You have to configure the expected type for JMSSerializer
Annotation :
/**
* #MongoDB\EmbedMany(targetDocument="Tag")
* #Type(ArrayCollection<App\DocumentBundle\Document\Tag>)
*/
private $tags;
Yaml :
tags:
expose: true
type: ArrayCollection<App\DocumentBundle\Document\Tag>
I've been trying to get an existing project working on local copy but have been countering alot of problems with the ODM and the dependencies.
I'm encountering this Sluggable issue :
[Semantical Error] The annotation "#Gedmo\Mapping\Annotation\Sluggable" in property
Cereals\ProductBundle\Document\Category\Specialty::$name does not exist, or could not be
auto-loaded.
And my Cereals...\Specialty file is such:
<?php
namespace Cereals\ProductBundle\Document\Category;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #MongoDB\Document(collection="Specialty",
repositoryClass="Cereals\ProductBundle\Repository\SpecialtyRepository")
*/
class Specialty
{
/**
* #MongoDB\Id(strategy="auto")
*/
protected $id;
/**
* #Gedmo\Sluggable
* #MongoDB\Index(order="asc")
* #MongoDB\String
*/
protected $name;
/**
* #MongoDB\String
* #MongoDB\UniqueIndex
* #Gedmo\Slug
*/
protected $slug;
/**
* #MongoDB\String
*/
I understand from Googling that there are some syntax updates for doctrine 2.1.x and I've used the new annotations for the #Gedmo\Mapping\Annotation\Sluggable here too.
Still the Semantical Error turns up.
Can anyone point some directions ? Thanks !
The #Gedmo\Sluggable annotation does not exisit. If you look in this folder, you will see this anottation is not implemented.
Actually, You can define your class like that:
<?php
namespace Cereals\ProductBundle\Document\Category;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #MongoDB\Document(collection="Specialty",
repositoryClass="Cereals\ProductBundle\Repository\SpecialtyRepository")
*/
class Specialty
{
/**
* #MongoDB\Id(strategy="auto")
*/
protected $id;
/**
* #MongoDB\Index(order="asc")
* #MongoDB\String
*/
protected $name;
/**
* #MongoDB\String
* #MongoDB\UniqueIndex
* #Gedmo\Slug(fields={"name"})
*/
protected $slug;
}
The #Gedmo\Slug annotation needs the properties which will be used for the slug generation.