简体   繁体   English

Sonata Admin MongoDB DataGrid过滤器

[英]Sonata Admin MongoDB DataGrid filter

Situation 情况

We are running Symfony 2.8 and the latest version of Sonata Admin along with Mongo as a data store. 我们正在运行Symfony 2.8和Sonata Admin的最新版本以及Mongo作为数据存储。 Please consider the following object which has been simplified for the sake of this question; 请考虑以下为简化此问题而简化的对象; it does work. 它确实有效。

class Entry
{
    /* @ID */
    protected $id;
    /* @String */
    protected $type;
    /* @String */
    protected $content;
}

With the above, there will be lots of entries and from the Admin itself, we would like to filter by type. 有了上面的内容,将会有很多条目,并且来自Admin本身,我们想按类型进行过滤。

Here's an example of the dataset 这是数据集的示例

示例数据集

Problem 问题

We can't create a set of selectable filters in the dataGrid function which are UNIQUE for type. 我们无法在dataGrid函数中创建一组唯一的类型可选过滤器。

Attempts 尝试次数

Note that where needed, the EntryRepository is included as a namespace at the start of the file 请注意,在需要的地方,EntryRepository作为文件开头的名称空间包含在内

NUMBER 1 1号

With the below, we get the type duplicated many times 在下面,我们得到了多次重复的类型

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

第一次尝试

NUMBER 2 2号

With the below, we get a 500 error with only the message "string". 在下面的代码中,我们仅显示消息“字符串”会出现500错误。 I think this is because when using distinct, Mongo prepares a set of arrays instead of unexecuted QueryBuilder object? 我认为这是因为在使用非重复时,Mongo准备了一组数组而不是未执行的QueryBuilder对象?

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

第二次尝试

NUMBER 3 3号

The attempt below is to use Map reduce to perform the equivalent of an SQL "GROUP BY" however, the same STRING error as above is provided. 下面的尝试是使用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; }');
        }
     ))

CRUDE WORKAROUND...discouraged 粗加工...变质

The below is a demonstration using the filter (as listed in the Sonata documentation) and it DOES work...for one type at a time. 以下是使用过滤器(如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'
))

Taken this approach, I think I'd have to go ahead and query the whole dataset getting the distinct values for type and then loop around each constructing the filter. 采用这种方法,我认为我必须继续进行查询整个数据集,以获取类型的不同值,然后遍历每个构造过滤器的地方。 This would work but be horribly messy. 这会起作用,但非常混乱。

QUESTION

What is the "best practise" way of performing this without turning the code in to a ruddy mess? 在不将代码变成混乱的情况下执行此操作的“最佳实践”方法是什么? Putting the query in a repository will still go and create a similar effect? 将查询放在存储库中仍然会产生类似的效果吗?

Thanks for reading 谢谢阅读

I'm posting the answer for anyone else who may be facing the same issue. 我将答案发布给可能面临相同问题的其他任何人。 I realised I was approaching the situation from the wrong angle and instead of any of the above, did the following 我意识到我是从错误的角度来对待这种情况,而不是上述任何一种情况,请执行以下操作

/* 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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM