【问题标题】:Query all objects based on entity property value?根据实体属性值查询所有对象?
【发布时间】:2015-11-20 07:47:19
【问题描述】:

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

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();
}

【问题讨论】:

    标签: php sql symfony doctrine-orm dql


    【解决方案1】:

    事实上,您的应用逻辑需要过于复杂,无法在您的应用程序中以其他方式执行。你不能简单地用 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());
    }
    

    【讨论】:

    • 谢谢你,但在我的情况下它不起作用。请看我的编辑!
    • 我可以看看你的产品实体吗?或者只是:variant 是另一个与 product 上的 ManyTo 关系的实体吗?
    • 给你:pastebin.com/nPuDDmPD 是的,变体是一对多关系
    • 我编辑了。试试吧,但我对这个请求有很大的怀疑。我认为您必须对变体进行子请求才能获得丰厚的回报
    • 完成。正如我在我的新答案中解释的那样:你不能在你的应用程序中做得更好。您必须通过 symfony 外部方式通过
    【解决方案2】:

    解决问题的不同方法:

    //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]);
    

    【讨论】:

    • 我也想过这个问题,但不是查询所有 besteller 对象并基于过滤器生成一个新数组在内存方面也过于矫枉过正吗?这样,我必须查询 2000 个对象,才能将 10 个对象添加到一个特殊的数组中……你怎么看?
    • 我同意,这不是“最干净”的选项。但是,2K 行不应该对性能产生真正的影响。无论如何,最好的方法就是 Julien 所描述的。
    【解决方案3】:

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

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

    最终,您可以迁移到基于事件的系统,在该系统中卖出股票会触发消息。一个完全独立的过程将监听这些消息并相应地更新您的报告表。这将两全其美。

    【讨论】:

    • 这与报告无关。我们需要这个百分比值在生产网站上实时计算一些东西......
    • 是同一个概念。在这种情况下,报告是一个 html 文档而不是一张纸。不妨看看 CSQ 模式:en.wikipedia.org/wiki/Command%E2%80%93query_separation
    猜你喜欢
    • 2019-12-30
    • 1970-01-01
    • 2015-08-08
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多