Tuesday, 22 October 2019

Obtain "rank" using Doctrine 2 ORM and OneToOne in Repository

I'm finding it almost impossible to achieve my desired result, after so many attempts with different solutions (sub query, raw query, etc) found here and on other websites, I must ask this question.

My goal is to extract/get each "projects" rank based on their "score".

Consider "score" as int and with values like 1,2,6,4,8,10,200, etc.

The rank would be like this:

Rank - Score

  1. 200
  2. 10
  3. 8
  4. 6

For my question to be as simple and clear as possible, I renamed my actual tables/entities as below:

MainEntity (main_table):

/**
* @ORM\Id
* @ORM\Column(name="id")
* @ORM\GeneratedValue
*/
protected $id;

// other fields, un-related to this question

/**
* @ORM\OneToOne(targetEntity="Application\Entity\SecondTable", mappedBy="second_table_data")
*/
protected $second_table;

/**
* @ORM\OneToOne(targetEntity="Application\Entity\ThirdTable", mappedBy="third_table_data")
* 
*/
protected $third_table;

SecondEntity (second_table):

/**
* @ORM\Id
* @ORM\Column(name="id")
* @ORM\GeneratedValue
*/
protected $id;

// other fields, un-related to this question

/**
* @ORM\OneToOne(targetEntity="Application\Entity\SecondTable", inversedBy="second_table")
* @ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
private $second_table_data;

ThirdEntity (third_table):

/**
* @ORM\Id
* @ORM\Column(name="id")
* @ORM\GeneratedValue
*/
protected $id;

// other fields, un-related to this question

/** 
 * @ORM\Column(name="score")  
 */
protected $score;

/**
* @ORM\OneToOne(targetEntity="Application\Entity\ThirdTable", inversedBy="third_table")
* @ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
private $third_table_data;

And the repository function to select "all projects" ordered by their score:

public function findAllProjects()
{
    $entityManager = $this->getEntityManager();

    $queryBuilder = $entityManager->createQueryBuilder();

    $queryBuilder->select('u')
       ->from(MainEntity::class, 'u')
       ->leftJoin('u.third_table', 't')
       ->orderBy('t.score', 'DESC');

    return $queryBuilder->getQuery()->getResult();
}

This works fine (I believe) as I get all the "projects" from main_table + second_table + third_table based on their "project_id".

However the issue is that I cannot find a way to calculate or get each project's "rank" number correctly. I also tried to use a "foreach" and use the "index" as "rank" but that will not work properly because I am using ORMPaginator so each time you click a "page" that "foreach" "index" will reset from 0.

I hope the question is clear enough and gives you a clear understanding of my problem.

Please advise how can I achieve this, and if my whole approach for this is wrong please point it out.

Every advice/hint/solution is highly appreciated.



from Obtain "rank" using Doctrine 2 ORM and OneToOne in Repository

No comments:

Post a Comment