Unicat API Reference

Up - API Reference - Home


The basic workings of search filters

Let's start with a quick look at a search request:

POST /api/p/<project gid>/schema/search
Authorization: Bearer <JWT>

{
    "q": "",
    "language": "nl",
    "filter": ["and", "", [
        ["is_committed", "is_true"],
        ["validation", "not_translated"]
    ]]
}

The filter property narrows down the results, based on field values, validation checks, and other properties. A filter supports boolean logic (AND, OR, NOT) and nesting.

A filter

Each filter is a triplet:

[property, operator, <operands>]

property what property are we looking at
operator how do we compare it
operands the value(s) to compare with the property, its format (or absence) depends on the operator.

The value of operands depends on both property and operator, e.g. it can be a single value or a list of values or combination of fieldname and value.

Boolean logic filters

There are three special properties that perform boolean logic:

and                 all clauses are true
or                  any clause is true
not                 invert truthfulness

These always have an empty operator.

The operands for boolean logic are filters themselves, as seen in the top example.

and and or have a list of operands, not has a single operand.

["and", "", [<A>, <B>, <C>]]
=> (<A> and <B> and <C>)


["or", "", [<A>, <B>, <C>]]
=> (<A> or <B> or <C>)

["not", "", <A>]
=> (not (<A>))

["not", "", ["and", "", [<A>, <B>, <C>]]]
=> (not (<A> and <B> and <C>))

["not", "", ["or", "", [<A>, <B>, <C>]]]
=> (not (<A> or <B> or <C>))

["not", "", ["not", "", <A>]]
=> (not (not (<A>)))

You can construct deeply nested filters using boolean logic. Keep it practical, though.

Typed filters

Whether we're filtering records, assets, or definitions, we will always construct filters based on the type of field we're working with. For example, 'name' is a text field, 'width' is a numeric field, and 'is_committed' is a boolean field.

Based on the type of data we are working with, there are a number of operators that can be used.

The operand is usually just a value, but when we filter on a record's field values (a value filter), the operand changes to a tuple (field, value).

["label", "q", "cms 335-945"]
["value", "q", ["name", "cms 335-945"]]

Text operators

This includes localized text fields.

q                   query, relevancy search (e.g. +cms -225)
is                  match entire field

The operand is quoted text.

["label", "q", "+article -accessory"]
["name", "is", "article"]

Note: case-sensitive matching is not supported

Path operators

is                  no subfolders
starts_with         include subfolders

The operand is a quoted path, always starting from the root /.

["path", "is", "/manuals/installation"]
["path", "starts_with", "/products"]

Numeric operators:

This includes both integer and decimal numbers.

=                   is
!=                  is not
<                   less than
<=                  less than or equal
>                   greater than
>=                  greater than or equal

The operand is a number.

["width", "=", 1024]
["size", "!=", 0]
["aspect_ratio", "<", 0.333]
["aspect_ratio", "<=", 0.333]
["aspect_ratio", ">", 3.0]
["aspect_ratio", ">=", 3.0]

Note: when we filter on a record's field values, the operand changes to a tuple (field, value)

["value", ">", ["price", 25.0]]

Boolean operators

is_true             is true
is_false            is false

There is no operand.

["is_committed", "is_true"]
["is_localized", "is_false"]

Date/time operators

<                   fewer than X days ago
>                   more than X days ago
between             between two timestamps

For < and >, the operand is a tuple of X and "days" (other periods are not supported), and it reads like 'the record was last updated fewer than 7 days ago'.

For between, the operand is a tuple of from-to timestamps in UNIX timestamp format (seconds since 1970).

["updated_on", "<", [7, "days"]]
["updated_on", ">", [7, "days"]]
["updated_on", "between", [946684800, 1629879544]]

List operators

has                 list includes search value
has_not             list doesn't include search value
<                   fewer than X items
<=                  fewer than or equal to X items
>                   more than X items
>=                  more than or equal to X items

For has and has_not, the operand depends on the type of the items in the list, so it could be a quoted text, or a number. They check the list for the given value.

For the other operators, the operand is a number. The number of items in the list is checked against this number. These operators are only used when we filter on a record's field values, so the operand changes to a tuple (field, value).

["channels", "has", "key-1"]
["channels", "has_not", "key-7"]
["value", "<", ["images", 10]]
["value", "<=", ["images", 10]]
["value", ">", ["images", 3]]
["value", ">=", ["images", 3]]

Select operators

When we can only filter on a select number of values - the value is picked from a list, and depending on the field we're evaluating we use is for value-types and has for list-types.

is                  data matches one from a list (fixed or generated from data)
has                 list data contains one from a list (fixed or generated)
["type", "is", "image"]
["channels", "has", "key-1"]

Definition operators

is                  matches this definition or extended definitions based on it
is_exactly          matches the definition exactly
like                matches the base definition of an extended definition

Specify the operand by gid or name.

["definition", "is", "article"]
["definition", "is_exactly", "chapter"]
["definition", "like", "228327f7-db98-4b59-9a7c-5db1235c62b6"]

Child-definition operators

A definition can specify a list of child-definitions.

When searching for records, we can check if the children of a record comply.

mixed_children      not all children have the exact same definition (even if that is allowed)
foreign_children    some have a definition that's not in the list (also empty list)
expected_children   the list isn't empty, but there are no children

There is no operand.

["childdefinitions", "mixed_children"]
["childdefinitions", "foreign_children"]
["childdefinitions", "expected_children"]

When searching for definitions, we can check if a childdefinition is included

has                 definition is in the child-definitions list

Specify the definition operand by gid or name.

["childdefinitions", "has", "articlegroup"]

Validation operators

Fields are validated, but not rejected if they fail validation. We can look for failed validations to generate a todo-list. The validation filter can be very specific (find records whose price-field has the wrong number of decimals), a tad specific (records whose price-field fails any validation, or records that have any not_translated fields), or generic (records that have any validation failure).

For records, we validate the fields from the definition.
For assets and schema items (definitions, classes, and fields), we validate name and label - for fields we also validate the (optional) 'initial' and 'values' settings for emptiness and translation.

errors

    invalid_input   invalid input for type (and optional format)

warnings (report)

    is_required     any field type
    min             numeric (number, decimal)
    max             numeric
    decimals        number of decimal places (decimal)
    min_items       lists (textlist, recordlist, imagelist, filelist)
    max_items       lists
    min_length      text (text, textline)
    max_length      text
    restrict_to_values (textline)

computed

    is_empty        field.length/items == 0 or field is null
    not_translated  field.is_localized and field.is_empty
    any             any failing validation

Generic:

["validation", "any"]

Slightly specific

["validation", "any", "price"]
["validation", "not_translated"]
["validation", "is_required"]

Highly specific

["validation", "decimals", "price"]
["validation", "is_required", "artnr"]
["validation", "not_translated", "description"]
["validation", "min_items", "upsell"]

Search-specific filters

We can search for records, assets, or schema items (definitions, classes, fields). Each has its own endpoint and set of supported filters. We'll give a quick list here, and provide links to the endpoint documentation for more detailed info.

Record filters

/api/p/<project gid>/records/search

updated_on                  datetime filter
validation                  validation filter (generic and specific)
definition                  record has a specific (extended) definition
classes                     record has a class (from definition)
fields                      record has a field (from definition classes and fields)
value                       record field value filters
channels                    check publication status
childdefinitions            either "mixed_children", "foreign_children", or "expected_children"
is_link                     record is a link, not an original
is_deleted                  deleted records can be undeleted

Asset filters

/api/p/<project gid>/assets/search

updated_on                  datetime filter
validation                  "is_empty" or "not_translated" (for title, description)
name                        text
ext                         filename extension, e.g. "eps" or "pdf"
path                        check folders
title                       text, localized
description                 text, localized
size                        file size in bytes
type                        either "file" or "image"
is_deleted                  deleted assets can be undeleted

extra filters for "image" type
    width                   in pixels
    height                  in pixels
    aspect_ratio            ratio w/h as a decimal number
    is_transparent          boolean
    is_animated             boolean
    colorspace              e.g. "cmyk" or "rgb"

Schema filters

/api/p/<project gid>/schema/search

validation                  "is_empty" or "not_translated" (for label)
name                        text
label                       text, localized
is_committed                not modified or new, for definitions, classes, fields
not_committed               modified or new, for definitions (but not extended), classes, fields
type                        either "definition", "class", or "field"
metadata                    metadata field value filters

extra filters for "definition" type
    classes                 definition has a class
    fields                  definition has a field (directly or through classes)
    childdefinitions        definition has a child definition

extra filters for "class" type
    fields                  class has a field

extra filters for "field" type
    unit                    text
    is_localized            is it a localized field
    is_required             is it a required field
    field_type              either "text", "textline", "textlist", "record", "recordlist",
                            "boolean", "number", "decimal", "image", "imagelist",
                            "file", "filelist", "code", or "barcode"

Examples

Asset examples

Assets updated in the past 7 days

["updated_on", "<", [7, "days"]]

Lo-res print images

["and", "", [
    ["type", "is", "image"],
    ["or", "", [
        ["width", "<=", 600],
        ["height", "<=", 600],
    ]],
]]

Lo-res web images

["and", "", [
    ["type", "is", "image"],
    ["or", "", [
        ["width", "<=", 300],
        ["height", "<=", 300],
    ]],
]]

Very tall or wide images

["and", "", [
    ["type", "is", "image"],
    ["or", "", [
        ["aspect_ratio", "<=", 0.333], // very tall
        ["aspect_ratio", ">=", 3], // very wide
    ]]
]]

Assets with missing translations of the title or description fields

["or", "", [
    ["validation", "not_translated", "title"],
    ["validation", "not_translated", "description"],
]]

Record examples

Records with mixed child definitions

["childdefinitions", "mixed_children"]

Records with unlisted child definitions

["childdefinitions", "foreign_children"]

Records with childdefinitions set but no children present

["and", "", [
    ["childdefinitions", "expected_children"],
]]

Records with any validation errors

["validation", "any"]

Records within price range with validation errors on name or image fields

["and", "", [
    ["or", "", [
        ["classes", "has", "article"],
        ["fields", "has", "price"],
    ]],
    ["and", "", [
        ["value", ">=", ["price",  0.00]],
        ["value", "<=", ["price", 10.00]],
    ]],
    ["or", "", [
        ["validation", "any", "name"],
        ["validation", "is_required", "image"],
    ]],
]]

Records with missing translations of the name and description fields in Channel Webshop or Catalog

["and", "", [
    ["or", "", [
        ["validation", "not_translated", "name"],
        ["validation", "not_translated", "description"],
    ]],
    ["or", "", [
        ["channels", "has", "650ebd0f-eab5-41d7-87c1-1dc5334af872"],
        ["channels", "has", "4782d5f5-b62b-4ecb-bf71-5be637a15dc5"],
    ]]
]]

Schema examples

Definitions with article class or artnr field

["and", "", [
    ["type", "is", "definition"],
    ["or", "", [
        ["classes", "has", "article"],
        ["fields", "has", "artnr"],
    ]],
]]

Classes with artnr or price field that are committed

["and", "", [
    ["type", "is", "class"],
    ["or", "", [
        ["fields", "has", "artnr"],
        ["fields", "has", "price"],
    ]],
    ["is_committed", "is_true"],
]]

Localized fields with unit kg

["and", "", [
    ["type", "is", "field"],
    ["is_localized", "is_true"],
    ["unit", "q", "kg"],
]]

Fields that have missing translations in any of the localized fields (label, initial, options, ... (initial, options only for is_localized fields))

["and", "", [
    ["type", "is", "field"],
    ["validation", "not_translated"],
]]