MongoDB ODM如何使用map / reduce对某个字段进行分组?

时间:2012-12-12 23:55:31

标签: php mongodb mapreduce doctrine doctrine-odm

我有一组文档,我想通过名为location的某个字段进行查询,按pos字段对其进行排序,并且只返回每个pos字段的最高值。

所以现在的查询看起来像这样:

$locations = array(1,2,3,4,5,6);

   $results = $this->dm->createQueryBuilder('\App\Document\Test')
        ->select('id', 'word', 'pos','change', 'title', 'coll_at', 'location')
        ->field('location')->in($locations)
        ->sort('location', 'asc')
        ->sort('pos', 'asc')
        ->getQuery()->execute();

但是因为每个具有不同location的特定pos可能有多个条目,所以我必须创建一个foreach循环来操作之后的数据。在这种情况下,我可以采用该快捷方式只是在返回数据之后更改数据,但我还有其他情况,根本不能这样做。所以我创建了这个较小的场景,试图找出如何使用Doctrine ODM的group查询,甚至是map&减少它。不确定最好的方法。我看到很多关于获得总计等的例子。

那么我如何创建一个查询来获取每个特定pos的{​​{1}}字段中的最高数值?知道可能存在多个具有相同location但具有不同location值的文档。最重要的是,在pos

中列出我在上面列出的所选记录的所有字段

2 个答案:

答案 0 :(得分:5)

您可以使用以下内容进行分组,而不是使用Map Reduce进行分组:

请注意,我相信Doctrines distinct的默认实现实际上适用于MongoDB的旧group()命令,但它基本上是一个MR包装:

  

那么我如何创建一个查询来获得每个特定位置的pos字段中的最高数值

这可能有用,但如果没有,那么你将需要使用聚合框架,但是在Doctrine中这有点困难,因为它们似乎没有真正的帮助器链接到它的框架的其余部分: https://github.com/doctrine/DoctrineMongoDBBundle/issues/165因此您必须使用command函数来运行它。

修改

我自己也是一个教条菜鸟,所以这是从例子中得出的:

$connection = $this->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
if(!$mongo){
    $connection->connect();
    $mongo = $connection->getMongo();
}
$db = $mongo->selectDB('test_database');
$aggregate_results = $db ->command(array( 
            "aggregate" => "my_collection",
            "pipeline" => 
                array( 
                    array( '$group' => array( 'location' => '$location', 'pos' => array('$sum' => '$pos'))),
                    array( '$sort' => array( "pos" =>1 ) )
                )
        ));

这会为你运行聚合,它不会完全是你想要的,我不会想到它而是玩它。

答案 1 :(得分:0)