Сортировка тегов по количеству связанных статей

Я хочу получить теги с соответствующими статьями. Однако цель состоит в том, чтобы отсортировать их по количеству связанных статей. Как этого добиться с помощью классов QueryBuilder и repositiry? Я новичок в symfony, и я пробовал получать теги с помощью DQL, но не получал целые объекты.

Теги и статьи находятся в отношении @ManyToMany:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass = "App\Repository\ArticleRepository")
 */
class Article
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @ORM\Column(type = "string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type = "string", length=255)
     */
    private $shortDescription;

    /**
     * @ORM\Column(type = "text")
     */
    private $content;

    /**
     * @ORM\Column(type = "float")
     */
    private $price;

    /**
     * @ORM\ManyToOne(targetEntity = "App\Entity\Category", inversedBy = "articles")
     */
    private $category;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\Tag", inversedBy = "articles")
     */
    private $tags;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\Author", inversedBy = "articles")
     */
    private $authors;

    public function __construct()
    {
        $this->tags = new ArrayCollection();
        $this->authors = new ArrayCollection();
    }


    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getShortDescription(): ?string
    {
        return $this->shortDescription;
    }

    public function setShortDescription(string $shortDescription): self
    {
        $this->shortDescription = $shortDescription;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getPrice(): ?float
    {
        return $this->price;
    }

    public function setPrice(float $price): self
    {
        $this->price = $price;

        return $this;
    }

    public function getCategory(): ?Category
    {
        return $this->category;
    }

    public function setCategory(?Category $category): self
    {
        $this->category = $category;

        return $this;
    }

    /**
     * @return Collection|Tag[]
     */
    public function getTags(): Collection
    {
        return $this->tags;
    }

    public function addTag(Tag $tag): self
    {
        if (!$this->tags->contains($tag)) {
            $this->tags[] = $tag;
        }

        return $this;
    }

    public function removeTag(Tag $tag): self
    {
        if ($this->tags->contains($tag)) {
            $this->tags->removeElement($tag);
        }

        return $this;
    }

    /**
     * @return Collection|Author[]
     */
    public function getAuthors(): Collection
    {
        return $this->authors;
    }

    public function addAuthor(Author $author): self
    {
        if (!$this->authors->contains($author)) {
            $this->authors[] = $author;
        }

        return $this;
    }

    public function removeAuthor(Author $author): self
    {
        if ($this->authors->contains($author)) {
            $this->authors->removeElement($author);
        }

        return $this;
    }

}

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass = "App\Repository\TagRepository")
 */
class Tag
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @ORM\Column(type = "string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\Article", mappedBy = "tags")
     */
    private $articles;

    public function __construct()
    {
        $this->articles = new ArrayCollection();
    }


    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return Collection|Article[]
     */
    public function getArticles(): Collection
    {
        return $this->articles;
    }

    public function addArticle(Article $article): self
    {
        if (!$this->articles->contains($article)) {
            $this->articles[] = $article;
            $article->addTag($this);
        }

        return $this;
    }

    public function removeArticle(Article $article): self
    {
        if ($this->articles->contains($article)) {
            $this->articles->removeElement($article);
            $article->removeTag($this);
        }

        return $this;
    }

}

Мой последний метод, который я использовал в TagRepository:

public function findTagsByArticlesCount()
{
          return $this->createQueryBuilder('tag')
              ->leftJoin('tag.articles', 'article')
              ->orderBy('count(article.id)', 'DESC')
              ->getQuery()
          ->execute();
}

пожалуйста, покажите нам свои операторы dql или querybuilder, которые вы пробовали до сих пор

LBA 29.08.2018 12:15

@LBA последний метод добавлен в сообщение выше

fabtosz 29.08.2018 12:42

вы пробовали stackoverflow.com/questions/6000622/…

LBA 29.08.2018 13:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
59
2

Ответы 2

Я смутно припоминаю похожий случай, который у меня был 2 года назад, который я смог решить, имея столбец HIDDEN:

public function findTagsByArticlesCount()
{
    return $this->createQueryBuilder('tag')
        ->leftJoin('tag.articles', 'article')
        ->addSelect('COUNT(article.id) as HIDDEN cnt')
        ->orderBy('cnt', 'DESC')
        ->getQuery()
        ->execute();
}

Однако в настоящее время я не нахожусь на своей рабочей станции, чтобы проверить это. Вы можете попробовать?

Надеюсь, поможет...

к сожалению нет. Интересно, есть ли возможность как обычно обрабатывать записи с помощью findAll, а затем как-то подсчитывать связанные статьи и делать соответствующие циклы или что-то в этом роде. однако я думаю, что он должен использоваться репозиторием и QB.

fabtosz 29.08.2018 13:09

При подсчете тегов в статьях отсутствует groupBy:

$this->createQueryBuilder('tag')
    ->leftJoin('tag.articles', 'article')
    ->addSelect('COUNT(tag.id) AS tagcount')
    ->groupBy('tag.id')
    ->orderBy('tagcount', 'DESC')
    ->getQuery()
    ->execute();

Примечание: при присоединении к Articles вы получите записи number of tags * number of articles, которые необходимо сгруппировать по тегам, чтобы подсчитать количество тегов в связанных статьях.

Примечание 2: я бы предпочел использовать innerJoin вместо leftJoin, а не выбирать теги без связанных статей.

Другие вопросы по теме