Select only matching embedded documents in an array field for the query
projection.

@see http://docs.mongodb.org/manual/reference/projection/elemMatch/

@param array|Expr $expression
546551
public function selectElemMatch(string $fieldName, $expression) : self
    {
        if ($expression instanceof Expr) {
            $expression = $expression->getQuery();
        }
        $this->query['select'][$fieldName] = ['$elemMatch' => $expression];
        return $this;
    }
956851
public function postProcessExpression(Expression $expression)
    {
        if ($this->hasHash($expression->hashCode())) {
            $alias = $this->getAlias($expression->hashCode());
            $alias = new Expr\Column($alias);
            $alias->setBuilder($this);
            $expression = new Expr\Raw(sprintf('%s AS %s', $expression->toSQL(), $alias->toSQL()));
        }
        
        return $expression;
    }
346490
public function dispatch(Expression $expr)
    {
        switch (true) {
            case $expr instanceof Comparison:
                return $this->walkComparison($expr);
            case $expr instanceof Value:
                return $this->walkValue($expr);
            case $expr instanceof CompositeExpression:
                return $this->walkCompositeExpression($expr);
            default:
                throw new RuntimeException('Unknown Expression ' . get_class($expr));
        }
    }
384010
function FilterFields($array, $operation = 'where') {
		if (!$array)
			return;
		$out = array();
		foreach ($array as $field => $value) {
			if ($operation == 'where' && $this->source == 'internal' && preg_match('/^(.*) (.*)$/', $field, $matches)) { // special CI syntax in key e.g. 'status !=' => 'something' (only for 'where' operations)
				$key = $matches[1];
				$cond = $matches[2];
				$val = $value;
			} elseif ($operation == 'where' && $this->source == 'controller' && is_string($value) && preg_match('/^([\<\>]=?)(.*)$/', $value, $matches)) { // CI syntax in value e.g. '>=value'
				$key = $field;
				$cond = $matches[1];
				$val = $matches[2];
			} elseif ($operation == 'where' && $this->source == 'controller' && is_array($value) && preg_match('/^([\<\>]=?)(.*)$/', $value[0], $matches)) { // CI syntax in value via array (e.g. ['>=value', '<=value'])
				// Accept an array of where conditions - this works around the fact that PHP will always accept the LAST where condition in an URL
				// e.g. ?foo=>1&foo=<10 (foo will == '<10')
				// Use ?foo[]=>1&foo[]=<10 to work around this
				$key = $field;
				$cond = $matches[1];
				$val = $matches[2];

				array_shift($value); // Remove first element - which we've already taken care of
				foreach ($value as $valIndex => $valArray) {
					if (preg_match('/^([\<\>]=?)(.*)$/', $value[$valIndex], $matches))
						$out[isset($matches[1]) && $matches[1] != '=' ? "$key {$matches[1]}" : $key] = $matches[2];
				}
			} else {
				$key = $field;
				$cond = '=';
				$val = $value;
			}

			if (!isset($this->schema[$key])) // Field definition does not exist at all
				continue;

			if ( // Is read-only during a 'set'
				$operation == 'set' &&
				isset($this->schema[$key]['allowset']) &&
				!$this->schema[$key]['allowset']
			)
				continue;

			if ( // Is not filterable by
				$operation == 'where' &&
				isset($this->schema[$key]['allowquery']) &&
				!$this->schema[$key]['allowquery']
			)
				continue;

			// If we got this far its a valid field
			$out[$cond && $cond != '=' ? "$key $cond" : $key] = $val;
		}
		return $out;
	}
184816
public function selectReduced( $expressions /* expressions ... */ ) {
		$expressions = is_array( $expressions ) ? $expressions : func_get_args();

		$this->setQueryForm( 'SELECT' );
		$this->uniqueness = 'REDUCED ';
		$this->addExpressions( $expressions );

		return $this;
	}
589988
public ArrayNode filter(ComparisonExpression expression) {
		
		ArrayNode result = new ObjectMapper().createArrayNode();
		if (node.isArray()) {
			Iterator<JsonNode> iterator = node.iterator();
			int validObjectsCount = 0;
			int topCount=0;
			while (iterator.hasNext()) {
				JsonNode curNode = iterator.next();
				if (expression==null || (expression!=null && new Query(curNode).is(expression))) {
					validObjectsCount++;
					if (this.skip != null && this.skip.intValue() > 0 && this.skip.intValue() >= validObjectsCount) {
						continue;
					}

					if (this.top != null && topCount >= this.top.intValue()) {
						break;
					}
					result.add(curNode);
					topCount++;
				}
			}
		} else {
			throw new UnsupportedExprException("Filters are only supported on ArrayNode objects");
		}
		return result;
	}
1054789
public function andX(array $expressions)
    {
        return function ($object) use ($expressions) {
            foreach ($expressions as $expression) {
                if (!$expression($object)) {
                    return false;
                }
            }

            return true;
        };
    }
250853
public static function filter(array $collection, $expression, array $context = [])
    {
        $language = new ExpressionLanguage();

        $result = [];
        foreach ($collection as $key => $item) {
            if ($language->evaluate($expression, array_merge($context, ['item' => $item, 'key' => $key]))) {
                $result[$key] = $item;
            }
        }

        return $result;
    }
1002831
protected function parseJsonArguments(string $expression) : array
    {
        // Prepara o json
        $expression = preg_replace('#\{\s*#','{', $expression);  // transoforma [ em { sem espaços
        $expression = preg_replace('#\s*\}#','}', $expression);  // transoforma ] em } sem espaços
        $expression = preg_replace('#\s*:#',':', $expression);    // remove espaçoes antes de :
        $expression = preg_replace('#:\s*#',':', $expression);    // remove espaçoes após de :
        $expression = preg_replace('#,\s*#',',', $expression);    // remove espaços antes das virgulas
        $expression = preg_replace('#\s*,#',',', $expression);    // remove espaços após as virgulas

        // Aspas
        $expression = preg_replace("#'([a-zA-Z0-9\_-]*)':#",'"$1":', $expression); // transforma 'xxx': em "xxx":
        $expression = preg_replace("#:'([a-zA-Z0-9\_-]*)'#",':"$1"', $expression); // transforma :'xxx' em :"xxx":
        $expression = preg_replace('#:([^"])#',':"$1', $expression);  // Adiciona aspas ausentes no inicio dos valores
        $expression = preg_replace('#([^"]),"#','$1","', $expression);// Adiciona aspas ausentes no final dos valores
        $expression = preg_replace('#([^"])}#','$1"}', $expression);  // Adiciona aspas ausentes no final do json

        $decoded = json_decode($expression, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \InvalidArgumentException('Invalid json syntax');
        }

        return $decoded;
    }
1049812
public function xpath($expression, $context = null)
    {
        if (is_array($expression)) {
            $tr = [];

            /** @noinspection ForeachSourceInspection */
            foreach ($expression as $k => $v) {
                $tr['$' . $k] = is_int($v) ? $v : "'$v'";
            }

            $expression = strtr($expression[0], $tr);
        }

        $r = @$this->_xpath->query($expression, $context);
        if ($r === false) {
            throw new MisuseException(['`:xpath` xpath is invalid expression', 'xpath' => $expression]);
        }

        return $r;
    }
848644
public function where($name, $expression = null)
    {
        foreach ($this->parseWhere($name, $expression) as $name => $expression) {
            $this->wheres[$name] = $expression;
        }

        return $this;
    }
134045
function matches($expression)
    {
        $parts = explode('.', $expression);

        // Defer evaluation of next expression to loop node.
        if (isset($parts[1])) {
            return ($this->loopNode->matches($parts[1]));
        }

        // Next expression is empty, hence it matches.
        return true;
    }
838524
public function execute(array $expressions)
    {
        $sum = 0;
        $exprLang = new ExpressionLanguage();

        foreach($expressions as $node => $clauses) {
            $value = NULL;

            if ($node != 'event'){
                EventValidator::isValidPropertyPath($node);

                // Get the value of the array node.
                eval(
                    'if(isset($this->data["properties"]' . $node . ') && !empty($this->data["properties"]' . $node . ')){'
                    . '$value = $this->data["properties"]' . $node . ';'
                    . '}'
                );
            }

            if($value == NULL && $node != 'event') {
                return $sum;
            }

            // Evaluate the clause and assign points accordingly.
            $result = 0;
            foreach ($clauses as $clause) {
                $result = (int)$exprLang->evaluate(
                    $clause, array(
                        'value' => $value,
                        'relationships' => $this->data['relationships'],
                ));
                if($result != 0) {
                    $sum = $sum + $result;
                    break;
                }
            }

        }

        return $sum;
    }
592493
public function select($expression = '*')
    {
        if (!is_array($expression)) {
            $expression = explode(',', $expression);
        }

        $this->type        = self::TYPE_SELECT;
        $this->expressions = array_merge($this->expressions, array_map(function ($expression, $alias) {
            return is_string($alias) ? "$expression AS $alias" : $expression;
        }, $expression, array_keys($expression)));

        return $this;
    }
514386
function _select (node, expr) {
        var
            resultSet,
            nodeSet = [node];
        while (expr) {
            resultSet = [];
            _test(nodeSet, expr, resultSet);
            if (0 === resultSet.length) {
                return [];
            }
            nodeSet = resultSet;
            if (expr.filter) {
                resultSet = [];
                _each(nodeSet, _filter, expr.filter, resultSet);
                if (0 === resultSet.length) {
                    return [];
                }
                nodeSet = resultSet;
            }
            expr = expr.then;
        }
        return resultSet;
    }
247299
public function passExpression(array $expression)
    {
        switch ($expression['type']) {
            case 'bool':
            case 'double':
            case 'int':
            case 'uint':
            case 'long':
            case 'ulong':
            case 'string':
            case 'istring':
            case 'null':
            case 'char':
            case 'uchar':
            case 'empty-array':
            case 'variable':
            case 'constant':
            case 'static-constant-access':
            case 'closure':
            case 'closure-arrow':
            case 'reference':
                break;

            case 'sub':
            case 'add':
            case 'div':
            case 'mul':
            case 'mod':
            case 'and':
            case 'or':
            case 'concat':
            case 'equals':
            case 'identical':
            case 'not-identical':
            case 'not-equals':
            case 'less':
            case 'greater':
            case 'greater-equal':
            case 'less-equal':
            case 'bitwise_and':
            case 'bitwise_or':
            case 'bitwise_xor':
            case 'bitwise_shiftleft':
            case 'bitwise_shiftright':
            case 'irange':
            case 'erange':
                $this->passExpression($expression['left']);
                $this->passExpression($expression['right']);
                break;

            case 'typeof':
            case 'not':
                $this->passExpression($expression['left']);
                break;

            case 'mcall':
            case 'fcall':
            case 'scall':
                $this->passCall($expression);
                break;

            case 'array':
                $this->passArray($expression);
                break;

            case 'new':
                $this->passNew($expression);
                break;

            case 'property-access':
            case 'property-dynamic-access':
            case 'property-string-access':
            case 'static-property-access':
            case 'array-access':
                $this->passExpression($expression['left']);
                break;

            case 'isset':
            case 'empty':
            case 'instanceof':
            case 'require':
            case 'clone':
            case 'likely':
            case 'unlikely':
            case 'ternary':
                /* do special pass later */
                $this->passExpression($expression['left']);
                break;

            case 'fetch':
                $this->increaseMutations($expression['left']['value']);
                $this->passExpression($expression['right']);
                break;

            case 'minus':
                $this->passExpression($expression['left']);
                break;

            case 'list':
                $this->passExpression($expression['left']);
                break;

            case 'cast':
            case 'type-hint':
                $this->passExpression($expression['right']);
                break;

            default:
                echo 'MutateGathererPassType=', $expression['type'], PHP_EOL;
                break;
        }
    }
834422
public Query<T> where(io.ebean.Expression expression) {
        return query().where(expression);
    }