Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 计算实体中的字段,按原则排序_Php_Symfony_Doctrine - Fatal编程技术网

Php 计算实体中的字段,按原则排序

Php 计算实体中的字段,按原则排序,php,symfony,doctrine,Php,Symfony,Doctrine,我有一个用户实体,它有一个计算字段totalPoints。现在我想让我的用户在一个高分的总分。我已经有了一个可行的解决方案,但目前只有150条记录的速度非常慢。我担心我迟早会有更多的唱片 在我的用户实体中,我有这个函数来计算点 public function getTotalPoints() { $totalPoints = 0; $totalPoints += $this->totalLevel; $totalPoints += $this

我有一个用户实体,它有一个计算字段totalPoints。现在我想让我的用户在一个高分的总分。我已经有了一个可行的解决方案,但目前只有150条记录的速度非常慢。我担心我迟早会有更多的唱片

在我的用户实体中,我有这个函数来计算点

public function getTotalPoints()
{
        $totalPoints = 0;
        $totalPoints += $this->totalLevel;
        $totalPoints += $this->getWeeksJoined() * $this->staticsRepository->findOnByName("Points Weeks Joined")->getValue();
        $totalPoints += $this->forumBumps * $this->staticsRepository->findOnByName("Points Forum Bumps")->getValue();
        $totalPoints += $this->lootSplit * $this->staticsRepository->findOnByName("Points Loot Split")->getValue();
        $totalPoints += $this->isVeteran * $this->staticsRepository->findOnByName("Points Veteran Rank")->getValue();
        $totalPoints += $this->getSotwPlaces(1)->count() * $this->staticsRepository->findOnByName("Points SOTW Wins")->getValue();
        $totalPoints += $this->getSotwPlaces(2)->count() * $this->staticsRepository->findOnByName("Points SOTW Second Place")->getValue();
        $totalPoints += $this->getSotwPlaces(3)->count() * $this->staticsRepository->findOnByName("Points SOTW 3rd Place")->getValue();
        $totalPoints += $this->osrsUserRefs->count() * $this->staticsRepository->findOnByName("Points Referals")->getValue();
        $totalPoints += $this->eventsAttended->count() * $this->staticsRepository->findOnByName("Points Events Attended")->getValue();
        $totalPoints += $this->eventsHosted->count() * $this->staticsRepository->findOnByName("Points Events Hosted")->getValue();

        if($this->discordUser != null)
            $totalPoints += $this->discordUser->getLevel() * $this->staticsRepository->findOnByName("Points Discord Level")->getValue();

        return $totalPoints;
    }
现在要按totalpoints排序,必须对用户数组进行排序,这很慢

/**
* @Route("/", name="highscores_index")
*/
    public function index(OsrsUserRepository $osrsUserRepository)
    {
        $osrsUsers = $osrsUserRepository->findAllHighscores();

        usort($osrsUsers, function($a, $b)
        {
            return $b->getTotalPoints() > $a->getTotalPoints();
        });

        return $this->render('highscores/index.html.twig', [
            'users' => $osrsUsers,
        ]);
    }

在条令查询生成器中是否有这样做的方法?我还没有找到任何关于这种排序的文档。

您的问题本质上是:

每次调用getTotalPoints。。。每个调用包括10个对staticsRepository fuckup的调用1:为什么你在一个实体中有一个存储库这是一种代码气味!并统计每个集合的子实体数+1个查询数

我真的很希望,您的staticsRepository不依赖于用户,因为在这种情况下,查询甚至不会被缓存。据你所知,他们可能不是

所以你基本上拥有的是

您可能可以编写一个专门的查询来计算数据库中所有用户的总分,但老实说,我不是来教您DQL或SQL的。但是,做研究,否则你就浪费了太多的改进潜力

现在,有一些选项列表不完整:

在数据库中执行所有操作,每次,每次。在本例中,您向UserRepository添加了一个函数,该函数为一个用户执行查询,或者返回所有用户,包括他们的总分。创建包含该查询字段的数据库视图可以使代码更加透明。但它也可以在querybuilder中完成,即DQL。。。或者SQL。也许你需要理论扩展

此解决方案具有相当高的性能,并且总是产生足够的最新结果

在php中实现逻辑,将结果存储在数据库中,为totalScore添加一个新的db字段,在方便的时间点重新计算。如果操作正确,此解决方案的性能非常好,但可能会产生稍微过时的结果。方便的时间点就像。。。每天午夜或每小时一次,或每5分钟一次-如果你的服务器可以阻止它,添加一些方法来确定分数是否发生了变化:给所有改变分数的内容加上时间戳,存储分数的时间戳

这个解决方案有点高性能,更新可能会通过cron作业完成,并且它总是产生正确的和最新的结果。-最近==您的间隔时间。本质上,它简化了您当前的方法。。。与1结合使用可获得非常好的效果

使用聚合字段,它基本上会更新数据库中的分数-几乎与第2个字段类似。但是——只要它改变了。看看并找出如何使其适应您的用例。请注意比赛条件以及如何避免。根据您的具体方法,这可能会降低许多操作的性能,但在要求高分时会大大提高性能

它在高分上表现得非常出色,而且总是能产生足够多的最新结果,但你必须处理比赛情况和所有分数更新,这可能非常烦人,并且容易出现错误

我的选择是1。这要求计算可以用sql或dql表示,这可能是可以完成的