根据实体属性值查询所有对象?

时间:2015-11-20 07:47:19

标签: php sql symfony doctrine-orm dql

我的实体中有自定义属性:

public function getStockSoldPercentage()
{
    return ($this->getStockSold() / $this->getFullStock()) * 100;
}

通过使用此属性,我可以访问已售罄的股票百分比。目前我使用像这样的查询

$bestellers = $this->getDoctrine()->getRepository('CoreBundle:Products')->findAll();

并直接在我的树枝模板中处理对象(所有产品的百分比高于75%)的过滤。所以你看,这在缩放方面并不是很好。当我每次用户访问网站时都要查询1000个产品时,是否过度杀伤......

我想构建一个自定义实体存储库,例如findAllBestSellers(),只查询getStockSoldPercentage()属性高于75的所有对象。

我该怎么做?

编辑:

getStockSold()getFullStock()不是字段,而是函数。它们看起来像这样:

public function getFullStock()
{
    $stock = 0;
    foreach ($this->variants as $variant) {
        $stock += $variant->getStock();
    }
    return $stock;
}

public function getStockSold()
{
    return $this->getFullStock() - $this->getCurrentStock();
}

3 个答案:

答案 0 :(得分:2)

事实上,您的应用逻辑需要太复杂,无法在您的应用程序中以另一种方式执行。您不能简单地在SQL中请求数据库以获得您想要的内容。

但是,我建议你创建一个sql函数,它返回你的产品并在其中记录你的所有逻辑。这样可以平衡应用服务器上的费用,而mysql的效率要高得多。

之后,您可以通过执行以下操作来调用您的函数:

public function findAllBestSellers() {

    $sql = "SELECT PRODUCTS_WITH_STOCK_SOLD_PERCENTAGE() AS products";
    $stmt = $this->dbal->executeQuery($sql);

    $stmt->execute();

    return current($stmt->fetch());
}

答案 1 :(得分:1)

解决问题的另一种方法:

//In your controller

$bestsellers = $this->getDoctrine()->getRepository('CoreBundle:Products')->findAll();

$results = [];

foreach ($bestsellers as $bestseller) {
    if ($bestseller->getStockSoldPercentage() >= '75') {
        $results[] = $bestseller;
    }
} 

return $this->render('YourTemplate.html.twig', ["results" = > $results]);

答案 2 :(得分:0)

这实际上是为什么许多应用程序将拥有两个数据库的典型示例。一个用于实时更新,第二个用于报告。

考虑每次出售股票时计算新的股票卖出百分比,然后将值存储在某个地方。这显然会减慢您的个人股票交易速度,但会大大加快您的报告查询速度。决定这是否是可接受的权衡取决于你。

最终,您可以转向更基于事件的系统,在该系统中,销售股票会触发消息。一个完全独立的过程会监听这些消息并相应地更新您的报告表。哪个会给两个世界带来最好的效果。