An expression to group documents by. To specify a field path, prefix the
field name with a dollar sign $ and enclose it in quotes.

@param mixed|Expr $expression

@return Stage\Bucket
974189
public function groupBy($expression)
    {
        assert($this->bucket instanceof Stage\Bucket);
        return $this->bucket->groupBy($expression);
    }
9091
public function addGroupBy(string ...$expression) : self
    {
        $this->groupByClauses = array_merge($this->groupByClauses, $expression);

        return $this;
    }
1152083
public function formatExpression(Expr $expr) {
        $field = $expr->getField();
        $operator = $expr->getOperator();
        $value = $expr->getValue();

        if ($operator === Expr::AS_ALIAS) {
            return sprintf($this->getClause(self::AS_ALIAS), $this->quote($field), $this->quote($value));

        // No value to use so exit early
        } else if (!$expr->useValue() && !($operator === Expr::NULL || $operator === Expr::NOT_NULL)) {
            return $this->quote($field);
        }

        $isSubQuery = ($value instanceof SubQuery);

        // Function as field
        if ($field instanceof Func) {
            $field = $this->formatFunction($field);

        // Raw expression as field
        } else if ($field instanceof RawExpr) {
            $field = $field->getValue();

        // Regular clause
        } else {
            $field = $this->quote($field);
        }

        // IN has special case
        if ($operator === Expr::IN || $operator === Expr::NOT_IN) {
            if ($isSubQuery) {
                $clause = sprintf($this->getClause($operator), $field, '?');
                $clause = str_replace(['(', ')'], '', $clause);
            } else {
                $clause = sprintf($this->getClause($operator), $field, implode(', ', array_fill(0, count($value), '?')));
            }

        // Operators with clauses
        } else if ($this->hasClause($operator)) {
            $clause = sprintf($this->getClause($operator), $field);

        // Basic operator
        } else {
            $clause = sprintf($this->getClause(self::EXPRESSION), $field, $operator);
        }

        // Replace ? with sub-query statement
        if ($isSubQuery) {
            /** @type \Titon\Db\Query\SubQuery $value */

            // EXISTS and NOT EXISTS doesn't have a field or operator
            if (in_array($value->getFilter(), [SubQuery::EXISTS, SubQuery::NOT_EXISTS], true)) {
                $clause = $this->formatSubQuery($value);

            } else {
                $clause = str_replace('?', $this->formatSubQuery($value), $clause);
            }
        }

        return $clause;
    }
1317833
public function sortByCount(string $expression) : Stage\SortByCount
    {
        $stage = new Stage\SortByCount($this, $expression, $this->dm, $this->class);
        $this->addStage($stage);

        return $stage;
    }
452153
public function set(string $column, Expr $expression)
    {
        $this->columnSetMap[$column] = $expression;

        return $this;
    }
76751
public function setExpression($expression)
    {
        if (is_string($expression)) {
            $expression = CronExpression::factory($expression);
        }

        $this->expression = $expression;

        return $this;
    }
556045
public function tokenize($expression)
    {
        if ($expression !== '') {
            $flags          = PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY;
            $this->iterator = new \CallbackFilterIterator(
                new \ArrayIterator(
                    preg_split(self::$expressionPartsPattern, $expression, 0, $flags)
                ),
                function ($value) {
                    //skip spaces
                    if ($value === ' ') {
                        return false;
                    }

                    //skip whitespaces but count newlines
                    if (rtrim($value) === '') {
                        $this->line += substr_count($value, "\n");

                        return false;
                    }

                    return true;
                }
            );
            $this->iterator->rewind();
        } else {
            $this->iterator = new \EmptyIterator();
        }

        return new Stream($this);
    }
1261925
private function fetchExpression($expression)
    {
        $selectors = explode(',', $expression);
        $paths = [];

        foreach ($selectors as $selector) {
            $selector = trim($selector);

            if (array_key_exists($selector, $this->compiledExpressions)) {
                $paths[] = $this->compiledExpressions[ $selector ];

                continue;
            }

            $this->compiledExpressions[ $selector ] = $this->fetchCssExpression($selector);

            $paths[] = $this->compiledExpressions[ $selector ];
        }

        return implode('|', $paths);
    }
1186514
private function query(string $expression): \DOMNodeList
    {
        return $this->xpath->query(
            $this->expressionTranslator->convertToXpath($expression)
        );
    }
590712
public static function expr() : ExpressionBuilder
    {
        if (self::$expressionBuilder === null) {
            self::$expressionBuilder = new ExpressionBuilder();
        }

        return self::$expressionBuilder;
    }
97945
public function setExpression($expression)
    {
        if (!is_string($expression) && !($expression instanceof JsExpression)) {
            throw new InvalidParamException('Expression must be a string or an instance of JsExpression');
        } elseif (($expression instanceof JsExpression) && $this === $expression) {
            throw new InvalidParamException('Expression cannot reference on self');
        }

        $this->expression = $expression;

        return $this;
    }
797562
public static function parseExpression($expression) {
    $tree = self::parseSource('<?php ' . $expression . ';');
    /** @var ExpressionStatementNode $statement_node */
    $statement_node = $tree->firstChild()->next();
    return $statement_node->getExpression()->remove();
  }
1336073
public function addGroupBy($expression)
    {
        if (!($expression instanceof Expression)) {
            $expression = new Column($expression);
        }
        
        $this->expressions->set($expression->hashCode(), $expression);
        
        return $this;
    }
618783
protected function _quoteOrderBy(OrderByExpression $expression)
    {
        $expression->iterateParts(function ($part, &$field) {
            if (is_string($field)) {
                $field = $this->_driver->quoteIdentifier($field);

                return $part;
            }
            if (is_string($part) && strpos($part, ' ') === false) {
                return $this->_driver->quoteIdentifier($part);
            }

            return $part;
        });
    }
176492
public function regexp($expression, $description = null): ValidatorChain
    {
        $rule = Validator::rule('regexp', [$expression]);
        if (null !== $description) {
            $rule->setDescription($description);
        }
        $this->addRule($rule);
        return $this;
    }
523136
public function normalizeExpression(Expression $expression)
    {
        $expression = $this->preProcessExpression($expression);
        
        switch (true) {
            // if has array parameters expression handle it recursively
            // if function expression extract from it all parameters and handle its
            case $expression instanceof Expr\Parameters:
            case $expression instanceof Expr\Func:
                
                $parameters = ($expression instanceof Expr\Func)
                    ? (new Expr\Parameters($expression->getParameters()))->getParameters()
                    : $expression->getParameters();
                
                foreach ($parameters as &$parameter) {
                    $parameter = $this->normalizeExpression($parameter);
                }
                
                $expression->setParameters($parameters);
                
                break;
            
            case $expression instanceof Expr\Table:
                
                if ($this->isReplaceAliases() === true) {
                    // replace table alias to real table name
                    if ($this->hasTableAlias($expression->getName())) {
                        $expression = $this->getTableByAlias($expression->getName());
                    }
                }
                
                break;
            
            // for column process it alias and real table if exist
            case $expression instanceof Expr\Column:
                
                if ($this->isReplaceAliases() === true) {
                    // replace column alias to real column name
                    if ($this->hasColumnAlias($expression->getName())) {
                        $expression = $this->getColumnByAlias($expression->getName());
                    }
                }
                
                break;
        }
        
        $expression = $this->postProcessExpression($expression);
        
        return $expression;
    }
914314
public function setExpression(string $expr) {
		$this->expression = $expr;
		$this->hasExpression = true;

		return $this;
	}