Skip to main content
Filters and sorting help you organize and find specific data in your tables. Apply powerful filter conditions and multi-level sorting to views for precise data control.

What are Filters?

Filters determine which records appear in a view by applying conditional logic. You can:
  • Filter by field values using comparison operators
  • Combine multiple conditions with AND/OR logic
  • Create nested filter groups
  • Apply date-based dynamic filters
  • Filter on computed fields (formulas, lookups, rollups)

40+ Operators

From simple equality to complex date ranges

Nested Groups

Build sophisticated AND/OR logic trees

Dynamic Filters

Relative dates like “Last 7 days” or “Next month”

View-Specific

Each view maintains its own filters

Filter Operators

NocoDB supports a comprehensive set of comparison operators:

Text Operators

OperatorDescriptionExample
eqEquals (exact match)Name is “John”
neqNot equalsStatus is not “Complete”
likeContains (case-insensitive)Email contains “@gmail”
nlikeDoes not containTitle doesn’t contain “Draft”
emptyIs empty stringDescription is empty
notemptyIs not empty stringNotes is not empty
nullIs null (no value)Manager is null
notnullIs not null (has value)Email is not null
blankIs blank (null or empty)Address is blank
notblankIs not blankPhone is not blank

Numeric Operators

OperatorDescriptionExample
eqEqualsPrice is 100
neqNot equalsQuantity is not 0
gtGreater thanAge greater than 18
ltLess thanStock less than 10
gte / geGreater than or equalScore greater than or equal to 80
lte / leLess than or equalDiscount less than or equal to 50
btwBetween (inclusive)Amount between 100 and 500
nbtwNot betweenPrice not between 10 and 20

Boolean Operators

OperatorDescriptionExample
checkedIs checked/trueActive is checked
notcheckedIs not checked/falseArchived is not checked

Select Field Operators

OperatorDescriptionExample
anyofMatches any of (OR)Status is any of [“Open”, “In Progress”]
nanyofMatches none ofPriority is none of [“Low”]
allofMatches all of (AND)Tags include all of [“Urgent”, “Bug”]
nallofDoes not match allLabels not all of [“Done”]
isExact matchCategory is “Sales”
isnotNot exact matchType is not “Internal”

Date & Time Operators

OperatorDescriptionExample
eqEquals exact dateDate is 2024-01-15
neqNot equals dateDue Date is not 2024-12-31
gtAfter dateCreated after 2024-01-01
ltBefore dateDeadline before 2024-12-31
gteOn or afterStart Date on or after 2024-06-01
lteOn or beforeEnd Date on or before 2024-06-30
isWithinWithin time periodModified is within last 7 days

Dynamic Date Filters

The isWithin operator supports relative date ranges:
Sub-OperatorDescription
todayToday
tomorrowTomorrow
yesterdayYesterday
oneWeekAgoExactly 7 days ago
oneWeekFromNowExactly 7 days from now
oneMonthAgoExactly 1 month ago
oneMonthFromNowExactly 1 month from now
pastWeekLast 7 days
pastMonthLast 30 days
pastYearLast 365 days
nextWeekNext 7 days
nextMonthNext 30 days
nextYearNext 365 days
pastNumberOfDaysCustom past X days
nextNumberOfDaysCustom next X days
daysAgoX days ago
daysFromNowX days from now
exactDateSpecific date
Source: query-filter-lexer.ts:10-73

Creating Filters

1

Open the view

Navigate to the view where you want to add filters
2

Click 'Filter'

Click the filter icon in the toolbar
3

Add filter condition

  • Select a field
  • Choose an operator
  • Enter the value to compare
4

Add more conditions (optional)

Click “Add Filter” to add additional conditions
5

Set logical operator

Choose AND or OR to combine conditions

Filter Structure

Filter Properties

PropertyDescriptionType
idUnique identifierstring
fk_view_idView this filter belongs tostring
fk_column_idField being filteredstring
comparison_opOperator (eq, gt, like, etc.)string
comparison_sub_opSub-operator (for dates)string
valueComparison valuestring
fk_parent_idParent filter (for nesting)string
is_groupIs this a group containerboolean
logical_opGroup logic (and/or/not)string
orderDisplay ordernumber
enabledIs filter activeboolean
Source: Filter.ts:26-56

Nested Filters

Create complex logic by nesting filter groups:
// Example: (Status is "Open" OR Priority is "High") AND Assigned is not null
{
  is_group: true,
  logical_op: 'and',
  children: [
    {
      is_group: true,
      logical_op: 'or',
      children: [
        { fk_column_id: 'status_id', comparison_op: 'eq', value: 'Open' },
        { fk_column_id: 'priority_id', comparison_op: 'eq', value: 'High' }
      ]
    },
    { fk_column_id: 'assigned_id', comparison_op: 'notnull' }
  ]
}

Managing Filters

Adding a Filter

const filter = await Filter.insert(context, {
  fk_view_id: viewId,
  fk_column_id: columnId,
  comparison_op: 'eq',
  value: 'Active',
  logical_op: 'and'
});

Creating Nested Filters

// Create parent group
const group = await Filter.insert(context, {
  fk_view_id: viewId,
  is_group: true,
  logical_op: 'or'
});

// Add child filters
await Filter.insert(context, {
  fk_view_id: viewId,
  fk_parent_id: group.id,
  fk_column_id: columnId1,
  comparison_op: 'eq',
  value: 'Value1'
});

await Filter.insert(context, {
  fk_view_id: viewId,
  fk_parent_id: group.id,
  fk_column_id: columnId2,
  comparison_op: 'gt',
  value: '100'
});

Updating a Filter

await Filter.update(context, filterId, {
  comparison_op: 'gte',
  value: '50',
  enabled: true
});

Deleting a Filter

// Deletes filter and all children recursively
await Filter.delete(context, filterId);
Source: Filter.ts:93-485

Sorting

Sorting controls the order in which records appear in a view. You can:
  • Sort by multiple fields
  • Choose ascending or descending order
  • Combine sorts for hierarchical ordering
  • Sort on any field type including formulas

Sort Directions

DirectionDescriptionUsage
ascAscending (A-Z, 0-9, oldest first)Alphabetical, chronological
descDescending (Z-A, 9-0, newest first)Reverse order
count-ascCount ascending (for link fields)Fewest links first
count-descCount descending (for link fields)Most links first
Source: Sort.ts:22

Creating Sorts

1

Open the view

Navigate to the view where you want to add sorting
2

Click 'Sort'

Click the sort icon in the toolbar
3

Add sort field

  • Select the field to sort by
  • Choose ascending or descending
4

Add secondary sorts (optional)

Add more sort levels for hierarchical ordering

Managing Sorts

Adding a Sort

const sort = await Sort.insert(context, {
  fk_view_id: viewId,
  fk_column_id: columnId,
  direction: 'desc',  // or 'asc'
  push_to_top: false  // Set true to add at top priority
});

Listing Sorts

// Get all sorts for a view (ordered by priority)
const sorts = await Sort.list(context, { viewId });

// Sorts are applied in order
// First sort has highest priority

Updating a Sort

await Sort.update(context, sortId, {
  fk_column_id: newColumnId,
  direction: 'asc'
});

Deleting Sorts

// Delete single sort
await Sort.delete(context, sortId);

// Delete all sorts for a view
await Sort.deleteAll(context, viewId);
Source: Sort.ts:16-278

Multi-Level Sorting

Sorts are applied in sequence. For example:
  1. First sort: Priority (High → Low)
  2. Second sort: Status (A → Z)
  3. Third sort: Due Date (Oldest → Newest)
Results will be ordered by Priority first, then by Status within each priority, then by Due Date within each status.
// Add priority sort
await Sort.insert(context, {
  fk_view_id: viewId,
  fk_column_id: priorityColumnId,
  direction: 'desc',
  order: 1
});

// Add secondary status sort
await Sort.insert(context, {
  fk_view_id: viewId,
  fk_column_id: statusColumnId,
  direction: 'asc',
  order: 2
});

// Add tertiary date sort
await Sort.insert(context, {
  fk_view_id: viewId,
  fk_column_id: dateColumnId,
  direction: 'asc',
  order: 3
});

Combining Filters and Sorts

Filters and sorts work together:
  1. Filters determine which records to show
  2. Sorts determine the order of those filtered records
// Filter: Show only active, high-priority items
await Filter.insert(context, {
  fk_view_id: viewId,
  is_group: true,
  logical_op: 'and',
  children: [
    { fk_column_id: statusCol, comparison_op: 'eq', value: 'Active' },
    { fk_column_id: priorityCol, comparison_op: 'eq', value: 'High' }
  ]
});

// Sort: Order by due date (earliest first)
await Sort.insert(context, {
  fk_view_id: viewId,
  fk_column_id: dueDateCol,
  direction: 'asc'
});

Performance Considerations

Add database indexes on frequently filtered columns for better performance.
Deeply nested filters with many conditions can slow down queries—simplify when possible.
eq is faster than like. Use exact matches when you can.
Filtering reduces the dataset before sorting is applied, improving performance.

Best Practices

Instead of reapplying filters repeatedly, create dedicated views with pre-configured filters.
“Last 7 days” automatically updates—better than filtering by specific dates that become stale.
Apply general filters first, then add specific conditions to narrow results.
Verify AND/OR combinations work as expected, especially with nested groups.
Add view descriptions explaining the purpose of complex filter configurations.

Common Filter Patterns

Show recent records

// Records from the last 30 days
{
  fk_column_id: createdTimeCol,
  comparison_op: 'isWithin',
  comparison_sub_op: 'pastMonth'
}

Show incomplete tasks

// Not complete AND (no due date OR due date in future)
{
  is_group: true,
  logical_op: 'and',
  children: [
    { fk_column_id: statusCol, comparison_op: 'neq', value: 'Complete' },
    {
      is_group: true,
      logical_op: 'or',
      children: [
        { fk_column_id: dueDateCol, comparison_op: 'null' },
        { fk_column_id: dueDateCol, comparison_op: 'gte', value: 'today' }
      ]
    }
  ]
}

Show assigned to me

// Collaborator includes current user
{
  fk_column_id: assignedCol,
  comparison_op: 'anyof',
  value: currentUserId
}

Views

Learn how filters and sorts apply to views

Formulas

Filter on computed formula fields

Fields

Understand field types and operators

API Filtering

Apply filters programmatically via API