Sonata Admin MongoDB DataGrid 过滤器

Posted

技术标签:

【中文标题】Sonata Admin MongoDB DataGrid 过滤器【英文标题】:Sonata Admin MongoDB DataGrid filter 【发布时间】:2016-05-28 19:30:19 【问题描述】:

情况

我们正在运行 Symfony 2.8 和最新版本的 Sonata Admin 以及 Mongo 作为数据存储。为了这个问题,请考虑以下已简化的对象;它确实有效。

class Entry

    /* @ID */
    protected $id;
    /* @String */
    protected $type;
    /* @String */
    protected $content;

有了上面的内容,会有很多条目,并且来自管理员本身,我们想按类型过滤。

这是数据集的示例

问题

我们无法在 dataGrid 函数中创建一组类型唯一的可选过滤器。

尝试

请注意,在需要的地方,EntryRepository 作为命名空间包含在文件的开头

第 1 个

通过下面,我们得到了重复多次的类型

->add('type', null, array(), 'document', array(
    'expanded' => true,
    'class' => 'Application:Entry',
    'query_builder' => function(EntryRepository $dr)  
        return $dr->createQueryBuilder();
    
))

第 2 个

在下面,我们得到一个 500 错误,只有消息“字符串”。我认为这是因为在使用 distinct 时,Mongo 准备了一组数组而不是未执行的 QueryBuilder 对象?

->add('type', null, array(), 'document', array(
    'expanded' => true,
    'class' => 'Application:Entry',
    'query_builder' => function(Entryepository $dr)  
        return $dr->createQueryBuilder()
        ->distinct('type');
    
))

数字 3

下面的尝试是使用 Map reduce 来执行相当于 SQL“GROUP BY”的操作,但是提供了与上面相同的 STRING 错误。

->add('type', '', array(), 'document', array(
    'expanded' => true,
    'class' => 'Application:Entry',
    'query_builder' => function(EntryRepository $dr) 
        return $dr->createQueryBuilder()
            ->group(array(), array('type'))
            ->reduce('function (obj, prev)  prev.type; ');
        
     ))

粗略的解决方法...不鼓励

以下是使用过滤器的演示(如 Sonata 文档中所列),它确实有效...一次只适用于一种类型。

->add('type', 'doctrine_mongo_callback', array(
    'callback' => function($queryBuilder, $alias, $field, $value) 
        if (!$value || $value['value'] == false) 
            return true;
        
        $queryBuilder
           ->field('type')->equals('fds');
           return true;
    ,
    'field_type' => 'checkbox'
))

采用这种方法,我想我必须继续查询整个数据集,获取类型的不同值,然后围绕每个构造过滤器进行循环。这可行,但非常混乱。

问题

在不将代码变成一团糟的情况下执行此操作的“最佳实践”方法是什么?将查询放在存储库中仍然会产生类似的效果吗?

感谢阅读

【问题讨论】:

【参考方案1】:

我正在为可能面临同样问题的其他人发布答案。我意识到我从错误的角度来处理这种情况,而不是上述任何一种,而是做了以下

/* Prepare the options to be used in the filter */
$tagRepo = $this->getConfigurationPool()->getContainer()->get('repository.tag');
$types = $tagRepo->findTypes();
$choices = array();
/* Create a simple choice compatible array */
foreach ($types as $type)  $choices[$type] = $type; 

/* In the actial filter itself */
$datagridMapper
->add('type', 'doctrine_mongo_choice', array(), 'choice',
  array('choices' => $choices))

【讨论】:

以上是关于Sonata Admin MongoDB DataGrid 过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Sonata admin 基于 ODM 的子管理员在基于 ORM 的管理员上

当sonata_type_admin调用时如何在Sonata的Admin类中获取底层对象?

Sonata 管理包:无法删除与 sonata_type_admin 的关系

服务“admin.category”依赖于不存在的服务“sonata.admin.manager.orm”

有没有办法确定 Sonata\AdminBundle\Admin\Admin::configureFormFields() 中的当前操作(创建或编辑)?

Sonata Admin Bundle - 自定义模板