/**
  * Gets the aggregation pipeline
  *
  * @param array $query
  * @param string $category
  * @param mixed $ranges
  * @return array
  */
 private function getAggregationPipeline(array $query, $category, $ranges)
 {
     $pipelineBuilder = new PipelineBuilder();
     $categoryQuery = array();
     $categoryQuery[] = array($category => array('$exists' => true));
     if (isset($ranges) && is_array($ranges) && $this->getRangeType($ranges) === static::MINMAX) {
         $categoryQuery[] = array('$or' => array(array($category => array('$type' => 1)), array($category => array('$type' => 16)), array($category => array('$type' => 18))));
     }
     unset($query[$category]);
     $query['$and'] = $categoryQuery;
     $match = new Match();
     $match->setQuery($query);
     $pipelineBuilder->add($match);
     if (is_array($ranges) && static::getRangeType($ranges) === static::MINMAX) {
         $rangeProjection = new RangeProjection();
         $rangeProjection->addRange($category, $ranges);
         $pipelineBuilder->add($rangeProjection);
     } else {
         $pipelineBuilder->addBuilder(new UnwindBuilder($category));
     }
     $group = new Group();
     $group->setGroupBy($category);
     $sum = new Sum();
     $sum->setSum(1);
     $group->setResultField('count', $sum);
     $pipelineBuilder->add($group);
     return $pipelineBuilder->build();
 }
 /**
  * Tests grouping some data.
  */
 public function testGroupData()
 {
     $testData = [['foo' => 'foo'], ['foo' => 'foo'], ['foo' => 'bar'], ['foo' => 'bar'], ['foo' => 'bar']];
     foreach ($testData as $test) {
         $this->collection->save($test);
     }
     $match = new Match();
     $match->setQuery(['foo' => 'foo']);
     $result = $this->collection->aggregate([$match->getStage()]);
     $this->assertEquals(2, count($result['result']));
 }