Collections\Criteria::expr(), isNotNull and notLike

2022-08-31 01:01:56

我正在使用(不是查询生成器表达式)。Doctrine\Common\Collections\Criteria::expr()

似乎 和 运算符未在此类中实现。isNotNull()notLike()

在这种情况下,最好的方法是什么?isNotNull()notLike()


答案 1

条件不为空

在或有一个,它的作用像一个你可以使用doctrine/orm ^2.4doctrine/collections ^1.2is not nullCriteria::expr()->isNotNull('field')

$criteria = Criteria::create();
$expr = $criteria::expr();
$collection->matching($criteria->where($expr->neq('field', null)));

这与表达式生成器创建的方式相同,但将比较运算符更改为 via:Expr::isNullComparison::NEQ

return new Comparison($field, Comparison::EQ, new Value(null));

然后由 QueryExpressionVisitor 和 检查,用于将查询构建为 。BasicEntityPersisterExpr:isNotNull

case Comparison::NEQ:
    if ($this->walkValue($comparison->getValue()) === null) {
        return $this->expr->isNotNull($this->rootAlias . '.' . $comparison->getField());
    }

标准喜欢和不喜欢

对于功能,相当于 SQL 。但是,它不允许更改或只是一个拉取请求(从2.5.4开始),建议和方法已与master合并 - 因此可以与2.5.5一起发布。Criteria::expr()->like()Criteria::expr()->contains('property', 'value')property LIKE %value%value%%valuestartsWithendsWith

不幸的是,对于和其他变体,Criteria使用的不支持它们。Criteria::expr()->notLike()LIKE\Doctrine\Common\Collections\ExpressionBuilder

此外,如果未定义比较运算符(如 Comparison::CONTAINS),则 and 会引发错误,这会阻止手动定义您自己的功能。QueryExpressionVisitorBasicEntityPersisterComparison

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections


自定义存储库备选方案

最好的替代方法是使用自定义存储库和 DBAL 查询生成器表达式来替换所需的功能。

使用自定义实体存储库筛选结果集将防止对集合进行全表读取,并提高使用缓存时的速度。

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#custom-repositories


收集过滤器替代方案

另一种方法是 使用 检索集合中对象的特定子集。filter

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr-class

class MyEntity
{
    public function getCollectionFieldNotLike($value)
    {
        return $this->getCollection()->filter(function($a) use ($value) {
            return (false === stripos($a->getField(), $value));
        });
    }

    public function getCollectionFieldLike($value)
    {
        return $this->getCollection()->filter(function($a) use ($value) {
            return (false !== stripos($a->getField(), $value));
        });
    }
}
$entity->getCollectionFieldNotLike('value');
$entity->getCollectionFieldLike('value');

用于存储库上两者的过程语法组合。

$criteria = Criteria::create();
$expr = $criteria::expr();
$criteria->where($expr->neq('field', null));
$collection = $entityManager->getRepository('app:MyEntity')->matching($criteria);
$collectionNotLike =  $collection->filter(function($a) {
    return (false === strpos($a->getField(), 'value'));
});

请记住,如上所述,这将强制对集合进行全表读取,因为它需要检索记录才能筛选结果。


答案 2

推荐