Skip to content

Filter Rules

Filters are used throughout the Likha ERP API to query items based on specific conditions. This page documents the complete filter syntax, operators, and advanced features.

Table of Contents


Available Operators

OperatorDescription
_eqEquals
_neqDoesn't equal
_ltLess than
_lteLess than or equal to
_gtGreater than
_gteGreater than or equal to
_inIs one of (array membership)
_ninIs not one of
_nullIs null
_nnullIsn't null
_containsContains (substring)
_ncontainsDoesn't contain
_icontainsContains (case-insensitive)
_nicontainsDoesn't contain (case-insensitive)
_starts_withStarts with
_istarts_withStarts with (case-insensitive)
_nstarts_withDoesn't start with
_nistarts_withDoesn't start with (case-insensitive)
_ends_withEnds with
_iends_withEnds with (case-insensitive)
_nends_withDoesn't end with
_niends_withDoesn't end with (case-insensitive)
_betweenIs between two values (inclusive)
_nbetweenIs not between two values (inclusive)
_emptyIs empty (null or falsy)
_nemptyIsn't empty (null or falsy)
_intersectsIntersects a point (geometry fields only)
_nintersectsDoesn't intersect a point (geometry fields only)
_intersects_bboxIntersects a bounding box (geometry fields only)
_nintersects_bboxDoesn't intersect a bounding box (geometry fields only)
_regexRegular expression (escape backslashes) - validation only
_someAt least one related value is true (relational)
_noneNo related values are true (relational)

Notes:

  • Numeric comparisons are not strictly typed, allowing comparisons between numbers and their string representations
  • Geometry operators only available on geometry fields
  • _regex only available in validation permissions
  • _some and _none only available on One-to-Many and Many-to-Many relationship fields

Filter Syntax

The basic filter structure is:

json
{
  "field": {
    "operator": "value"
  }
}
  • field can exist on the current collection or a relational collection
  • operator must be any valid filter operator
  • value can be any static value or dynamic variable

Simple Example

Filter items where the title contains "article":

json
{
  "title": {
    "_contains": "article"
  }
}

Relational Fields

You can filter items based on related data by nesting field names.

Many-to-One Relations

Filter based on fields of the related item:

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

This filters articles where the related author's name equals "Rijk van Zanten".

Many-to-Many Relations

For Many-to-Many relationships, you filter through the junction table:

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

For a books collection with a Many-to-Many relationship to authors (via a books_authors junction table), you need to go through the junction table and the foreign key field.


_some vs _none

These operators filter One-to-Many and Many-to-Many relational fields.

_some Operator

Matches items where at least one related item meets the condition. This is the default behavior for relational queries.

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

The above explicitly uses _some. Since it's the default, this is equivalent:

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

_none Operator

Matches items where none of the related items meet the condition.

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

This matches items where no category has the name "Recipe".


Dynamic Variables

Dynamic variables are replaced with runtime values when the query executes.

VariableDescription
$CURRENT_USERThe primary key of the currently authenticated user
$CURRENT_ROLEThe primary key of the role for the currently authenticated user
$NOWThe current timestamp
$NOW(<adjustment>)The current timestamp plus/minus a distance (e.g., $NOW(-1 year), $NOW(+2 hours))

Examples

Filter items created by the current user:

json
{
  "owner": {
    "_eq": "$CURRENT_USER"
  }
}

Filter items from the last week:

json
{
  "published_date": {
    "_gte": "$NOW(-1 week)"
  }
}

In permissions configuration, you can access nested fields:

json
{
  "$CURRENT_ROLE.name": "admin"
}

Logical Operators

Combine multiple filter rules using _and or _or logical operators. Each holds an array of filter rules. Logical operators can be nested.

Structure

json
{
  "_and": [
    { "field1": { "operator": "value" } },
    { "field2": { "operator": "value" } }
  ]
}

Complex Example

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

Functions

Functions accept a field and return a modified value. Use them in any query parameter where you'd normally supply a field key (including fields, aggregation, and filters).

Syntax: function(field)

FunctionDescription
year()Extract year from datetime/date/timestamp
month()Extract month from datetime/date/timestamp
week()Extract week from datetime/date/timestamp
day()Extract day from datetime/date/timestamp
weekday()Extract weekday from datetime/date/timestamp
hour()Extract hour from datetime/date/timestamp
minute()Extract minute from datetime/date/timestamp
second()Extract second from datetime/date/timestamp
count()Count items in JSON array or relational field
json()Extract value from JSON field using path notation

Example

Filter items published in April 1968:

json
{
  "_and": [
    {
      "year(published_date)": {
        "_eq": 1968
      }
    },
    {
      "month(published_date)": {
        "_eq": 4
      }
    }
  ]
}

Follow Syntax

The $FOLLOW(target-collection, relation-field) syntax allows querying indirect relations when no direct relation field exists in the current collection.

Use Case

When you have two collections (e.g., countries and cities) where cities has a Many-to-One relation to countries via country_id, but the countries collection has no direct relation field to cities. You can still filter countries based on city fields.

Example

Find countries that have a city named "Berlin":

json
{
  "filter": {
    "name": "Germany",
    "$FOLLOW(cities, country_id)": {
      "name": "Berlin"
    }
  }
}

This filters the countries collection by following the relation to cities through the country_id field.


Usage in API Requests

When making API requests, filters are passed as a query parameter:

http
GET /items/articles?filter={"status":{"_eq":"published"}} HTTP/1.1

Notes

  • Filter keys are case-sensitive and must match field names exactly
  • For complex filters, consider URL encoding the JSON when using raw HTTP
  • The filter parameter can be combined with other query parameters like sort, limit, offset
  • Not all operators are available in all contexts (e.g., _regex is validation-only)
  • Test complex filters in a safe environment before deploying to production
  • Use the fields parameter to limit returned data when using filters with relational fields to avoid over-fetching