我正在使用Symfony 2.3和doctrine 1.2
我有以下实体结构,包括Product,Tag和TagCategory。 Product与Tag具有ManyToMany关系,Tag与TagCategory具有ManyToOne关系
产品类别:
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 存储库:
$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"]=>**
}
}
}
}
谢谢。
答案 0 :(得分:2)
您要执行的操作无法在SQL级别上使用单个查询完成。
您可以使用子查询进行2次查询或1次查询。 仍然可以在背景中做到这一点,但我不认为教条可以做到这一点。我怀疑教义1. *能够。
无论如何,如果您不需要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,然后通过id在foreach循环中对其进行配对。
答案 1 :(得分:0)
在下面的代码中有一些误区
joinColumns = {@ ORM \ JoinColumn(name =“cod_pro”,referencedColumnName =“cod_pro”)},
应该是
joinColumns = {@ ORM \ JoinColumn(name =“cod_pro”,referencedColumnName =“id”)},