Добавьте свойство к дочерней сущности в ассоциации с QueryBuilder Doctrine

Я работаю с 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"]=>**
}
}
}
}

Спасибо.

3

Решение

То, что вы хотите сделать, нельзя сделать одним запросом на уровне 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 по идентификатору.

2

Другие решения

В приведенном ниже коде произошла ошибка

joinColumns = {@ ORM \ JoinColumn (name = «cod_pro», referencedColumnName = «cod_pro»)},

должно быть

joinColumns = {@ ORM \ JoinColumn (name = «cod_pro», referencedColumnName = «id»)},

0