Я работаю с Symfony 2.3 и доктриной 1.2
У меня есть следующая структура сущности, с Product, Tag и TagCategory. Product имеет отношение ManyToMany с Tag, а Tag имеет отношение ManyToOne с TagCategory
Класс продукта:
class Product
{
/**
* @var ArrayCollection List of tags
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="products")
* @ORM\JoinTable(name="tags_productos",
* joinColumns={@ORM\JoinColumn(name="cod_pro", referencedColumnName="cod_pro")},
* inverseJoinColumns={@ORM\JoinColumn(name="cod_tag", referencedColumnName="id")}
* )
*/
protected $tags;
}
Класс TagCategory:
class TagCategory extends BaseTagCategory
{
/**
* @ORM\OneToMany(targetEntity="Tag", mappedBy="category", orphanRemoval=true)
*/
protected $tags;
}
Класс тегов:
class Tag extends BaseTag
{
/**
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="TagCategory", inversedBy="tags")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false)
*/
protected $category;
/**
* @var ArrayCollection List of products that have this tag assigned
*
* @ORM\ManyToMany(targetEntity="Product", mappedBy="tags")
*/
protected $products;
}
Что мне нужно сделать, так это получить для определенного списка продуктов теги, которые имеют эти продукты, и для каждого тега получить количество продуктов, имеющих этот тег.
Я также хочу получить теги, сгруппированные по TagCategory, потому что они должны быть сгруппированы.
Вот один из запросов, которые я пытался TagCategory Repository:
$qb->select('c as tagCategory, t as tag, COUNT(t) as total')
->from($this->_entityName, 'c')
->leftJoin('c.tags', 't')
->leftJoin('t.products', 'p')
->where(
$qb->expr()->in('p.id', $productsIds)
)
->groupBy('t.id')
;
Это дает мне массив со следующей структурой:
array(3) {
[0]=> array(2) {
["tagCategory"]=> array(4) {
["id"]=>
["name"]=>
["slug"]=>
["tags"]=> array(2) {
[0]=> array(4) {
["id"]=>
["order"]=>
["name"]=>
["slug"]=>
}
[1]=> array(4) {
["id"]=>
["order"]=>
["name"]=>
["slug"]=>
}
}
}
["total"]=>
}
Этот запрос группирует все теги в категории, чего я и хочу, но он помещает итоговое значение на верхний уровень и как итоговое значение последнего тега в категории. Мне нужно общее как другое свойство Тег юридическое лицо.
Я также пытался сделать этот запрос, в Тег репозиторий:
$qb->select('c as tagCategory, t as tag, COUNT(t) as total')
->from($this->_entityName, 't')
->leftJoin('t.category', 'c')
->leftJoin('t.products', 'p')
->where(
$qb->expr()->in('p.id', $productsIds)
)
->groupBy('t.id')
;
Этот запрос дает мне массив тегов, с категорией и итогом как свойством, и это правильно, но мне нужно, чтобы теги были сгруппированы внутри категории:
array(4) {
[0]=> array(2) {
["tag"]=> array(5) {
["id"]=>
["order"]=>
["name"]=>
["slug"]=>
["category"]=> array(3) {
["id"]=>
["name"]=>
["slug"]=>
}
}
["total"]=>
}
Мне нужно что-то вроде этого, это можно сделать?
array(3) {
[0]=> array(2) {
["tagCategory"]=> array(4) {
["id"]=>
["name"]=>
["slug"]=>
["tags"]=> array(2) {
[0]=> array(4) {
["id"]=>
["order"]=>
["name"]=>
["slug"]=>
**["total"]=>**
}
[1]=> array(4) {
["id"]=>
["order"]=>
["name"]=>
["slug"]=>
**["total"]=>**
}
}
}
}
Спасибо.
То, что вы хотите сделать, нельзя сделать одним запросом на уровне SQL.
Вы можете сделать это с 2 запросами или 1 запросом с подзапросом.
Тем не менее, доктрина, вероятно, могла бы сделать это на заднем плане, но, как я не думаю, что доктрина2. * Может сделать это. Я сомневаюсь, что doctrine1. * Сможет.
В любом случае, если вам не нужны все данные из tagCategory, лучшим решением будет изменение вашего второго запроса и выбор необходимых дополнительных полей.
$qb->select('c as tagCategory, t as tag, COUNT(t) as total, c.name as tagCategory_name')
->from($this->_entityName, 't')
->leftJoin('t.category', 'c')
->leftJoin('t.products', 'p')
->where(
$qb->expr()->in('p.id', $productsIds)
)
->groupBy('t.id')
;
Если вам нужны все данные и точная структура, как вы описали, выберите все tagCategories одним запросом, а затем соедините их в цикле foreach по идентификатору.
В приведенном ниже коде произошла ошибка
joinColumns = {@ ORM \ JoinColumn (name = «cod_pro», referencedColumnName = «cod_pro»)},
должно быть
joinColumns = {@ ORM \ JoinColumn (name = «cod_pro», referencedColumnName = «id»)},