Compare left- and right-size of: value <op> value.

        :param lhs_value: Value to left of operator
        :param rhs_value: Value to right of operator
        :return: True if the comparison is valid
        :rtype: bool

def compare(self, lhs_value, rhs_value):
        """Compare left- and right-size of: value <op> value.

        :param lhs_value: Value to left of operator
        :param rhs_value: Value to right of operator
        :return: True if the comparison is valid
        :rtype: bool
        """
        if self.is_eq():
            # simple {field:value}
            return lhs_value is not None and lhs_value == rhs_value
        if self.is_neq():
            return lhs_value is not None and lhs_value != rhs_value  # XXX: 'or'?
        if self.is_exists():
            if rhs_value:
                return lhs_value is not None
            else:
                return lhs_value is None
        if self.is_size():
            if self.is_size_eq() or self.is_size_var():
                return lhs_value == rhs_value
            if self.is_size_gt():
                return lhs_value > rhs_value
            if self.is_size_lt():
                return lhs_value < rhs_value
            raise RuntimeError('unexpected size operator: {}'.format(self._op))
        if self.is_inequality():
            if not isinstance(lhs_value, Number):
                return False
            py_op = self.PY_INEQ.get(self._op, self._op)
            return eval('{} {} {}'.format(lhs_value, py_op, rhs_value))
        if self.is_type():
            ltype = type(lhs_value)
            if rhs_value is Number:
                return ltype in (int, float)
            elif rhs_value is str:
                return ltype is str
            elif rhs_value is bool:
                return ltype is bool
            return False
        if self.is_regex():
            m = rhs_value.match(lhs_value)
            return m is not None