{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "filter": {
            "$ref": "#/definitions/bool"
        }
    },
    "additionalProperties": false,
    "definitions": {
        "field": {
            "type": "string"
        },
        "value": {
            "type": [
                "string",
                "number",
                "boolean",
                "array",
                "object"
            ]
        },
        "range": {
            "type": "array"
        },
        "filter_type": {
            "type": "string",
            "enum": [
                "bool",
                "match",
                "in",
                "exist",
                "compare"
            ]
        },
        "filters_allowed": {
            "oneOf": [
                {
                    "$ref": "#/definitions/basic_filter"
                },
                {
                    "$ref": "#/definitions/exist"
                },
                {
                    "$ref": "#/definitions/bool"
                },
                {
                    "$ref": "#/definitions/compare"
                }
            ]
        },
        "basic_filter": {
            "type": "object",
            "properties": {
                "filter_type": {
                    "$ref": "#/definitions/filter_type"
                },
                "field": {
                    "$ref": "#/definitions/field"
                },
                "value": {
                    "$ref": "#/definitions/value"
                },
                "range": {
                    "$ref": "#/definitions/range"
                }
            },
            "oneOf": [
                {
                    "required": [
                        "field",
                        "value",
                        "filter_type"
                    ]
                },
                {
                    "required": [
                        "field",
                        "range",
                        "filter_type"
                    ]
                }
            ],
            "additionalProperties": false
        },
        "exist": {
            "type": "object",
            "properties": {
                "filter_type": {
                    "$ref": "#/definitions/filter_type"
                },
                "field": {
                    "$ref": "#/definitions/field"
                }
            },
            "required": [
                "field",
                "filter_type"
            ],
            "additionalProperties": false
        },
        "compare": {
            "type": "object",
            "properties": {
                "filter_type": {
                    "$ref": "#/definitions/filter_type"
                },
                "field1": {
                    "$ref": "#/definitions/field"
                },
                "field2": {
                    "$ref": "#/definitions/field"
                },
                "constant": {
                    "$ref": "#/definitions/constant"
                },
                "comparison_operator": {
                    "$ref": "#/definitions/comparison_operator"
                }
            },
            "oneOf": [
                {
                    "required": [
                        "field1",
                        "field2",
                        "comparison_operator",
                        "filter_type"
                    ]
                },
                {
                    "required": [
                        "field1",
                        "constant",
                        "comparison_operator",
                        "filter_type"
                    ]
                }
            ],
            "additionalProperties": false
        },
        "constant": {
            "type": [
                "string",
                "number"
            ]
        },
        "comparison_operator": {
            "type": "string",
            "enum": [
                "lt",
                "gt",
                "lte",
                "gte",
                "eq"
            ]
        },
        "bool": {
            "type": "object",
            "properties": {
                "filter_type": {
                    "$ref": "#/definitions/filter_type"
                },
                "must": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/filters_allowed"
                    }
                },
                "must_not": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/filters_allowed"
                    }
                },
                "should": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/filters_allowed"
                    }
                }
            },
            "additionalProperties": false
        }
    }
}