Filter expressions are not initialized directly. Instead they are built
    by combining RedisFilterFields using the & and | operators.
    Examples:
        >>> from langchain_community.vectorstores.redis import RedisTag, RedisNum
        >>> brand_is_nike = RedisTag("brand") == "nike"
        >>> price_is_under_100 = RedisNum("price") < 100
        >>> filter = brand_is_nike & price_is_under_100
        >>> print(str(filter))
        (@brand:{nike} @price:[-inf (100)])
    """
[docs]    def __init__(
        self,
        _filter: Optional[str] = None,
        operator: Optional[RedisFilterOperator] = None,
        left: Optional["RedisFilterExpression"] = None,
        right: Optional["RedisFilterExpression"] = None,
    ):
        self._filter = _filter
        self._operator = operator
        self._left = left
        self._right = right
    def __and__(self, other: "RedisFilterExpression") -> "RedisFilterExpression":
        return RedisFilterExpression(
            operator=RedisFilterOperator.AND, left=self, right=other
        )
    def __or__(self, other: "RedisFilterExpression") -> "RedisFilterExpression":
        return RedisFilterExpression(
            operator=RedisFilterOperator.OR, left=self, right=other
        )
[docs]    @staticmethod
    def format_expression(
        left: "RedisFilterExpression", right: "RedisFilterExpression", operator_str: str
    ) -> str:
        _left, _right = str(left), str(right)
        if _left == _right == "*":
            return _left
        if _left == "*" != _right:
            return _right