使用symfony2 / doctrine2,我很难为我的查询定义索引。
我的代码:
$queryBuilder = $this->_em
->createQueryBuilder()
->select('u, uis, cost, p, stock')
->from('AppBundle:FoodAnalytics\UserIngredient', 'u', 'p.id')
->leftJoin('u.product', 'p')
->leftJoin('u.numberObjects', 'stock')
->leftJoin('u.userIngredientSuppliers', 'uis')
->leftJoin('uis.numberObjects', 'cost')
->where('u.user = ?1')
->setParameter(1, $portfolioUser)
;
我收到以下错误:
[Semantical Error] line 0, col 110 near 'p LEFT JOIN u.numberObjects': Error: 'p' is already defined.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
[1/2] QueryException: SELECT u, uis, cost, p, stock FROM AppBundle:FoodAnalytics\UserIngredient u INDEX BY p.id LEFT JOIN u.product p LEFT JOIN u.numberObjects stock LEFT JOIN u.userIngredientSuppliers uis LEFT JOIN uis.numberObjects cost WHERE u.user = ?1 +
使用u.product
我收到以下错误:
[Semantical Error] line 0, col 87 near 'product LEFT': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
仅使用product
,我收到以下错误:
[Semantical Error] line 0, col 85 near 'product LEFT': Error: 'product' does not point to a Class.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
如果我使用u.id
,它可以正常工作
我可以只使用同一个表中某个字段的索引吗?
我该怎么做才能让它发挥作用?
Thansk很多!
编辑:
作为我正在使用的临时修复:
$result = $queryBuilder->getQuery()->getResult();
$result = array_combine(array_map(function(UserIngredient $userIngredient){
return $userIngredient->getProduct()->getId();
}, $result), $result);
return $result;
答案 0 :(得分:4)
属性indexBy
仅适用于您当前正在选择的实体,正如您猜到的那样(和AFAIK);因此,在您的情况下,您只能按u.id
索引。
这对我来说很有意义,因为来自其他实体的索引确实搞砸了返回的结果。您获得正确结果的唯一情况是:
在其他每种情况下,你都会在水化过程中松开一些实例参考。
在您的示例中,您正在使用LEFT JOIN:没有产品的所有实体会发生什么?全部丢弃,所以LEFT JOIN会让工人像INNER JOIN一样。此外,您的解决方法建议您要组合具有相同索引的实体,但这不是Doctrine的工作方式:在Doctrine中,indexBy列必须是唯一的。有关详细信息,请参阅the official docs。
请注意,您可以在JOIN子句中使用index p.id
,但这有不同的含义。这意味着在对UserIngredients实例进行保湿时,应该通过id。
所以,我的建议是遵循这两个解决方案中的一个:
Product -> UserIngredients
,请使用Product
作为查询的主要实体(from子句,首先出现在select中),然后按p.id
索引使用哪一个取决于您的业务逻辑,但我通常更喜欢第二个解决方案,因为第一个生成多级数组,更好地用实体关系表示。
希望这有帮助! :)