Skip to content
On this page

Filter Rules

Permissions, validation, and the API's filter parameter all rely on a specific JSON structure to define their rules. This page describes the syntax for creating flat, relational, or complex filter rules.

Syntax

{
	<field>: {
		<operator>: <value>
	}
}
{
	<field>: {
		<operator>: <value>
	}
}

Examples

json
{
	"title": {
		"_contains": "Directus"
	}
}
{
	"title": {
		"_contains": "Directus"
	}
}
json
{
	"owner": {
		"_eq": "$CURRENT_USER"
	}
}
{
	"owner": {
		"_eq": "$CURRENT_USER"
	}
}
json
{
	"datetime": {
		"_lte": "$NOW"
	}
}
{
	"datetime": {
		"_lte": "$NOW"
	}
}
json
{
	"category": {
		"_null": true
	}
}
{
	"category": {
		"_null": true
	}
}

Filter Operators

Operator Title (in app)OperatorDescription
Equals_eqEqual to
Doesn't equal_neqNot equal to
Less than_ltLess than
Less than or equal to_lteLess than or equal to
Greater than_gtGreater than
Greater than or equal to_gteGreater than or equal to
Is one of_inMatches any of the values
Is not one of_ninDoesn't match any of the values
Is null_nullIs null
Isn't null_nnullIs not null
Contains_containsContains the substring
Contains (case-insensitive)_icontainsContains the case-insensitive substring
Doesn't contain_ncontainsDoesn't contain the substring
Starts with_starts_withStarts with
Starts with_istarts_withStarts with, case-insensitive
Doesn't start with_nstarts_withDoesn't start with
Doesn't start with_nistarts_withDoesn't start with, case-insensitive
Ends with_ends_withEnds with
Ends with_iends_withEnds with, case-insensitive
Doesn't end with_nends_withDoesn't end with
Doesn't end with_niends_withDoesn't end with, case-insensitive
Is between_betweenIs between two values (inclusive)
Isn't between_nbetweenIs not between two values (inclusive)
Is empty_emptyIs empty (null or falsy)
Isn't empty_nemptyIs not empty (null or falsy)
Intersects_intersects [1]Value intersects a given point
Doesn't intersect_nintersects [1]Value does not intersect a given point
Intersects Bounding box_intersects_bbox [1]Value is in a bounding box
Doesn't intersect bounding box_nintersects_bbox [1]Value is not in a bounding box

The following operator has no Title on the Filter Interface as it is only available in validation permissions:

OperatorDescription
_regex [2]Field has to match regex

[1] Only available on Geometry types.
[2] JavaScript "flavor" regex. Make sure to escape backslashes.

Relational

You can target related values by nesting field names. For example, if you have a relational Many-to-One author field, you can set a rule for the author.name field using the following syntax.

json
{
	"author": {
		"name": {
			"_eq": "Rijk van Zanten"
		}
	}
}
{
	"author": {
		"name": {
			"_eq": "Rijk van Zanten"
		}
	}
}

When using M2M relationships, a junction table will be created and the filter applies to the junction table itself. For example, if you have a books collection, with a M2M relationship to authors of each book, the junction collection will probably be named books_authors and have 3 fields : id, books_id and authors_id. To filter specific books depending on their authors you must go through the junction table and the authors_id field :

json
{
	"authors": {
		"authors_id": {
			"name": {
				"_eq": "Rijk van Zanten"
			}
		}
	}
}
{
	"authors": {
		"authors_id": {
			"name": {
				"_eq": "Rijk van Zanten"
			}
		}
	}
}

Logical Operators

You can nest or group multiple rules using the _and or _or logical operators. Each logical operator holds an array of Filter Rules, allowing for more complex filtering. Also note in the example that Logical Operators can be sub-nested into Logical Operators. However, they cannot be sub-nested into Filter Rules.

json
{
	"_or": [
		{
			"_and": [
				{
					"user_created": {
						"_eq": "$CURRENT_USER"
					}
				},
				{
					"status": {
						"_in": ["published", "draft"]
					}
				}
			]
		},
		{
			"_and": [
				{
					"user_created": {
						"_neq": "$CURRENT_USER"
					}
				},
				{
					"status": {
						"_in": ["published"]
					}
				}
			]
		}
	]
}
{
	"_or": [
		{
			"_and": [
				{
					"user_created": {
						"_eq": "$CURRENT_USER"
					}
				},
				{
					"status": {
						"_in": ["published", "draft"]
					}
				}
			]
		},
		{
			"_and": [
				{
					"user_created": {
						"_neq": "$CURRENT_USER"
					}
				},
				{
					"status": {
						"_in": ["published"]
					}
				}
			]
		}
	]
}

Some vs None in One-to-Many

When applying filters to a one-to-many field, Directus will default to a "some" search, for example in:

json
{
	"categories": {
		"name": {
			"_eq": "Recipe"
		}
	}
}
{
	"categories": {
		"name": {
			"_eq": "Recipe"
		}
	}
}

the top level parent will be returned if one of the categories has the name Recipe. This behavior can be overridden by using the explicit _some and _none operators, for example:

json
{
	"categories": {
		"_none": {
			"name": {
				"_eq": "Recipe"
			}
		}
	}
}
{
	"categories": {
		"_none": {
			"name": {
				"_eq": "Recipe"
			}
		}
	}
}

will fetch all parent items that don't have the category "Recipe"

Dynamic Variables

In addition to static values, you can also filter against dynamic values using the following variables.

  • $CURRENT_USER — The primary key of the currently authenticated user
  • $CURRENT_ROLE — The primary key of the role for the currently authenticated user
  • $NOW — The current timestamp
  • $NOW(<adjustment>) - The current timestamp plus/minus a given distance, for example $NOW(-1 year), $NOW(+2 hours)

Functions

You can also use Function Parameters when building Filters.

Nested User / Role variables in Permissions

When configuring permissions, $CURRENT_USER and $CURRENT_ROLE allow you to specify any (nested) field under the current user/role as well as the root ID. For example: $CURRENT_ROLE.name or $CURRENT_USER.avatar.filesize. This includes custom fields that were added to the directus_users/directus_roles tables.

Note: This feature is available for permissions, validation, presets and conditional fields. Regular filters only support the root ID.

Dynamic Variables not available in Flows

Although certain Operations in Flows use filter rules, dynamic variables are not available in Flows.