Sonata/Symfony MongoDB过滤Null值:ODM替代ORM isNull的方法
解决Doctrine MongoDB ODM中筛选Null字段的问题
嘿,这个问题我刚好踩过坑!Doctrine MongoDB ODM的Expr类确实没有isNull()方法——因为MongoDB查询null的逻辑和SQL不一样,咱们得换个适配的写法。
正确的实现方式
在MongoDB里,匹配字段为null的文档,对应的查询条件是{"field": null},所以在ODM中,你需要用field()->equals(null)来生成这个条件。
把你代码里的这一行:
$queryBuilder->andWhere($queryBuilder->expr()->isNull($alias.'.mainCategory'));
替换成:
$queryBuilder->andWhere($queryBuilder->expr()->field($alias.'.mainCategory')->equals(null));
或者更简洁的写法(直接调用QueryBuilder的field方法,不用绕expr):
$queryBuilder->field($alias.'.mainCategory')->equals(null);
修改后的完整代码片段
->add("isRoot", 'doctrine_mongo_callback', array( 'callback' => function ($queryBuilder, $alias, $field, $value) { /** @var QueryBuilder $queryBuilder */ if ($value['value']) { if ($value['value'] == 0) { // 替换为ODM支持的null查询写法 $queryBuilder->andWhere($queryBuilder->expr()->field($alias.'.mainCategory')->equals(null)); return true; } else { $category = $this->getConfigurationPool()->getContainer()->get('doctrine_mongodb.odm.document_manager')->getReference(ArticleCategory::class, $value['value']); $queryBuilder->andWhere($queryBuilder->expr()->eq($alias.'.category', $category)); return true; } } }, 'field_type' => ChoiceType::class, 'field_options' => array( 'choices' => $this->getCategoryChoices() ), 'label' => 'mainCategory' ));
额外说明
如果你的需求是严格匹配字段存在且值为null(而不是字段不存在的情况),那需要结合exists(true):
$queryBuilder->andWhere( $queryBuilder->expr()->field($alias.'.mainCategory')->exists(true)->equals(null) );
因为MongoDB中{"field": null}会同时匹配字段值为null和字段不存在的文档,你可以根据实际业务需求选择对应写法。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

