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

时间:2014-10-30 12:59:06

标签: php doctrine-orm

我正在使用Doctrine\Common\Collections\Criteria::expr() 查询构建器表达式)。

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

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

1 个答案:

答案 0 :(得分:16)

要让is not nullCriteria::expr()->isNotNull('field')一样使用

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

这与表达式构建器创建isNull的方式相同,但是将比较运算符更改为NEQ

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

然后由QueryExpressionVisitorBasicEntityPersister检查,用于构建查询。

对于Criteria::expr()->like()功能,Criteria::expr()->contains('property', 'value')等同于SQL property LIKE %value%。但是,它不允许更改为value%%value,而是pull request (从2.5.4开始)与建议的startsWith和{ {1}}已与master合并的方法 - 因此可能会以2.5.5发布。

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

此外,如果未定义比较运算符(例如\Doctrine\Common\Collections\ExpressionBuilder,则CONTAINSQueryExpressionVisitor会引发错误,从而阻止手动定义您自己的BasicEntityPersister功能。

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


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

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

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

对于存储库的两者的程序语法组合。

$repo->getCollectionFieldNotLike('value');
$repo->getCollectionFieldLike('value');

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