Adds to a "GROUP BY" clause

@param string[] $expression,... A variable list of expressions of what to group by
@return self For method chaining
9091
public function addGroupBy(string ...$expression) : self
    {
        $this->groupByClauses = array_merge($this->groupByClauses, $expression);

        return $this;
    }
1316035
public function addOrderBy(string ...$expression) : self
    {
        $this->orderBy = array_merge($this->orderBy, $expression);

        return $this;
    }
105907
public function passNew(array $expression)
    {
        if (isset($expression['parameters'])) {
            foreach ($expression['parameters'] as $parameter) {
                $usePass = self::DETECT_PARAM_PASS == ($this->detectionFlags & self::DETECT_PARAM_PASS);
                if ($usePass && 'variable' == $parameter['parameter']['type']) {
                    $this->increaseMutations($parameter['parameter']['value']);
                } else {
                    $this->passExpression($parameter['parameter']);
                }
            }
        }
    }
727994
public function batchDelete($expression)
    {
        // remove
        $result = $this->getMongoCollection()->remove(
            Expression::convertToArray($expression)
        );

        // check result
        if (true !== $result && $result['ok'] != 1) {
            throw new Exception('Error removing documents from collection: ' . $result['err']);
        }

        return $this;
    }
1056895
private function operator(string $operator, $expression) : self
    {
        if ($this->currentField) {
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
        } else {
            $this->expr[$operator] = $this->ensureArray($expression);
        }

        return $this;
    }
754828
public function addFilter(string $expression): CopyDictionaryJob
    {
        // Check if the first and last char match - if not, we must encapsulate with '/'.
        if ($expression[0] !== substr($expression, -1)) {
            $expression = '/' . $expression . '/';
        }

        // Test if the regex is valid.
        try {
            preg_match($expression, '');
        } catch (\Throwable $error) {
            throw new \InvalidArgumentException(
                sprintf('Filter "%s" is not a valid regular expression - Error: %s', $expression, $error->getMessage()),
                0,
                $error
            );
        }

        $this->filters[] = $expression;

        return $this;
    }
352454
public function setOrderBy($expression, $vector = OrderBy::ASC)
    {
        if (!($expression instanceof Expression)) {
            $expression = new Column($expression);
        }
        
        $this->setExpression($expression)->setVector($vector);
        
        return $this;
    }
756117
public function elemMatch($expression) : self
    {
        return $this->operator('$elemMatch', $expression instanceof Expr ? $expression->getQuery() : $expression);
    }
546551
public function selectElemMatch(string $fieldName, $expression) : self
    {
        if ($expression instanceof Expr) {
            $expression = $expression->getQuery();
        }
        $this->query['select'][$fieldName] = ['$elemMatch' => $expression];
        return $this;
    }
248056
private function ensureArray($expression)
    {
        if (is_array($expression)) {
            $array = array();
            foreach ($expression as $index => $value) {
                $array[$index] = $this->ensureArray($value);
            }

            return $array;
        } elseif ($expression instanceof self) {
            return $expression->getExpression();
        }

        return $expression;
    }
900392
public function addExpressionCondition($expression) {
        if(!isset($this->_subscription->subject)){
            $this->_subscription->subject = (object) [];
        }

        if(!isset($this->_subscription->subject->condition)){
            $this->_subscription->subject->condition = (object) [];
        }


        $this->_subscription->subject->condition->expression = $expression;
        return $this;
    }
998870
public function valuesExpr($expression) {
		$args = func_get_args();
		$this->expression = array_shift($args);
		
		if (empty($args))
			return $this;
		
		//check if argument is a list
		try {
			$this->valuesArray($args[0]);
		}
		catch (\InvalidArgumentException $e) {
			$this->valueList = $args;
		}
		
		return $this;
	}
792082
public function addGroupBy($field)
    {
        $this->groupByFields = array_merge(
            $this->groupByFields,
            is_array($field) ? $field : func_get_args()
        );

        return $this;
    }
465155
public function groupBy(string $column)
    {
        $this->addGroupBy($this->dialect()->quoteName($column));

        return $this;
    }
389398
final public function value(string $expression): Collection\StringCollection
    {
        $items = $this->query($expression);
        $result = [];
        foreach ($items as $node) {
            $result[] = $node->nodeValue;
        }
        return new StringCollection($result);
    }
1318851
public function addExpression($expression)
    {
        if (!$this->expressions->contains($expression)) {
            $this->expressions[] = $expression;
        }

        return $this;
    }
75122
private static function treeStruct(string $expression): array
    {
        if (\strpos($expression, '<?') === 0 || $expression[-1] === ';') {
            throw new \InvalidArgumentException('Expression syntax error');
        }

        $expression = '<?php ' . $expression . ';';

        $tokens = \token_get_all($expression);

        $temp = [];
        $level = 0;

        $n = \count($tokens);
        $i = 1; // skip T_OPEN_TAG
        for (; $i < $n; ++$i) {
            $token = $tokens[$i];

            $type = null;
            if (\is_array($token)) {
                $type = $token[0];

                if ($type === T_WHITESPACE) {
                    continue;
                }

                if (!\in_array($type, self::SUPPORT_TOKEN, true)) {
                    throw new \InvalidArgumentException('Expression contains not support token "' . \token_name($type) . '""');
                }

                if ($type === T_INC && ($tokens[$i - 1] === '+' || $tokens[$i + 1] === '+')) {
                    throw new \InvalidArgumentException('Expression contains error code: "+++');
                }

                if ($type === T_DEC && ($tokens[$i - 1] === '-' || $tokens[$i + 1] === '-')) {
                    throw new \InvalidArgumentException('Expression contains error code: "---');
                }
            }

            switch ($token) {
                case '?':
                    $part = $temp[$level];

                    if ($level === 0) {
                        $temp[$level++] = [$part, new Token($token)];
                    } else {
                        $parentLevel = $level - 1;
                        $temp[$parentLevel][] = $part;
                        $temp[$parentLevel][] = new Token($token);
                    }

                    $temp[$level] = [];
                    break;

                case ':':
                    if ($level === 0) {
                        throw new \InvalidArgumentException('Expression ternary syntax error');
                    }

                    $part = $temp[$level];

                    $parentLevel = $level - 1;
                    $temp[$parentLevel][] = $part;
                    $temp[$parentLevel][] = new Token($token);

                    $temp[$level] = [];
                    break;

                case ';':
                    if ($level > 0) {
                        $part = $temp[$level];
                        unset($temp[$level]);

                        $temp[--$level][] = $part;
                    }
                    ++$i;
                    break 2;
                case ')':
                case ']':
                    $temp[$level][] = new Token($token);
                    $part = $temp[$level];
                    unset($temp[$level]);

                    $temp[--$level][] = $part;
                    break;

                case '(':
                case '[':
                    $temp[++$level] = [new Token($token)];
                    break;

                default:
                    $temp[$level][] = new Token($token);
            }
        }

        if ($i !== $n) {
            throw new \InvalidArgumentException('The code has multi-line expression');
        }

        if (\count($temp) > 1) {
            throw new \InvalidArgumentException('Expression syntax error');
        }

        return $temp[0];
    }