Describes how to build and use expressions.

Expressions are a set of conditions that can be grouped in different ways using AND and OR operators. These expressions can be evaluated against a record, which will return true if the record matches the expression or false otherwise.

Additionally these expressions can be easily converted to queries in the database, so they are used when we need to fetch all records that match the expression.

Expressions could be replaced by scripts in most of the cases (and you will have the option when that’s possible), but if you can define your conditions using expressions it is recommended to do so for the following reasons:

  • Maintainability: they are automatically refactored when fields are modified, so you don’t have to worry in most cases.
  • Usability: expressions can be created using the UI, which is more intuitive and easier to master.
  • Database queries: most expressions can be applied directly to the database, so you will see that in cases where queries are necessary, you won’t be able to write scripts (like access permissions).

Expressions point to a target entity, which is the entity that contains the records the expression can be evaluated against. They basically have set of conditions than can be organized using AND and OR groups.

Each filter has a reference to a field in the target entity (the Target field) which is the field that is going to be filtered (except By user value, see below), an Operator used to filter the field (available operators depends on the type of the field), and a value used to filter. The value used to filter could be hard-coded (By value or By user value), it could come from a field in a record (By record field) or from a field in the user extended fields record (By user field).

You can combine groups and conditions to build complex expressions. For example it could be something like this:

- AND
  - By value: type = 'a'
  - OR
    - By value: state = 'inactive'
    - By value: name like 'test'

Expressions are a generic concept that is used in several places in the app definition. For that reason it is very important to pay attention to the context to understand what’s the target entity and what could be the source entity (in conditions of type By record field).

For example, in a By value condition in a read/write access in an entity field, the target entity will be the one holding the field. On the other hand, if the condition is of type By record field in the filter of a relationship field, the target entity will be the entity the relationship points to while the source entity is the entity holding the relationship field.

Groups

AND

All elements inside this group need to evaluate to true to make the group itself evaluate to true. If one or more elements evaluate to false, then the whole group will be evaluated as false.

It is possible to have OR groups inside AND groups.

OR

Any element inside this group needs to evaluate to true to make the group itself evaluate to true. If all elements evaluate to false, the the group will be evaluated as false.

It is possible to have AND groups inside OR groups.

Conditions

Conditions have the following form:

Target Field - Operator - Value

For example:

type - Equals - 'a'

The difference between the types of conditions are how the Value is set. It could be hard-coded (By value or By user value), it could come from a field in a record (By record field) or from a field in the user extended fields record (By user field).

It is important to understand how it works when there are multi-valued fields or many values.

When the target field is single-valued and there are many values, if any of the values matches the value of the target field, the condition will evaluate to true.

When the target field is multi-valued and there is only one value, if the value matches any of the values of the target field, the condition will evaluate to true.

Finally, when target field is multi-valued and there are many values, if any of the values matches any of the values in the target field, the condition will evaluate to true.

By value

In these type of conditions the value is hard-coded. Depending on the selected operator it will be possible to specify one or more values.

By record field

In this case the value will be obtained from a field in a record (the Source field).

For example, when configuring filters of a relationship field, you could filter records of the target entity by saying that their field type should be equals to the value of the companyType field in the source record instead of providing a hard-coded value. This way the results of the filter will be different from record to record as the value of companyType could be different.

By user field

User conditions are based on the User extended fields feature, so it must be enabled in the app before using this type of condition.

In this case the value will be obtained from the field in the user extended record (the Source field) of the current user. This means that these conditions will only work when there is a current user set and there is a user extended fields record associated to it when the condition is evaluated, otherwise this condition will evaluate to false.

For example you could have the field companies in the user extended fields entity that indicates for which companies users work for. Then there could be a tasks entity with a company field. If you want that users only see tasks for companies they work for, you could add a condition By user field in the permissions for the tasks entity where the target field is company and the source field is companies (in the user extended fields entity).

By user value

This filter is a mix between By user field and By value. Here, value is hard-coded as By value, but the Target field belongs to entity configured into User extended fields.

Operation

It is the operation used to filter the field. Available operations depends on the type of the field defined in field (check docs for the type), but it could be one of these operations:

equals: equivalent to an any condition tests if the any element of current value is in the filter value

notEquals: equivalent to an not in condition tests if the current value is not in the filter value

like: similar to equals but matches partially every value

between: operator which defines two extremes of a range where current value should eb placed

greater: exactly equivalent to math operator for number types

greaterOrEquals: exactly equivalent to math operator for number types

less: exactly equivalent to math operator for number types

lessOrEquals: exactly equivalent to math operator for number types

empty: the current value must be a null or empty list

notEmpty: the current value must be not null and not empty list

Query format

Expressions can be represented with query language, which is useful when you need to pass expressions in scripts. For example:

// this is a simple query expression where field 'company' should be equals to 'GOOGLE'
{
  company: 'GOOGLE'
}

// this query expression is to filter by companies with 'type' in 'a' or 'b',
// or with 'numberOfPeople' greater or equals to 100
{
  _or: {
    type: ['a', 'b'],
    numberOfPeople: 'greaterOrEquals(100)'
  }
}

// this query expression is to filter companies by the related company to the logged user
{
  name: 'currentUserField(company.name)'
}

The way to map filters is using the field name and the value to filter for. Inside value we can put an operation. Available operations depends on the type of the field defined in field (check docs for the type), but it could be one of these operations:

  • equals
  • notEquals
  • like
  • between
  • greater
  • greaterOrEquals
  • less
  • lessOrEquals
  • empty
  • notEmpty
  • currentUserField

To learn more about query language and the valid operators please check the docs for Complex Query Language.

Back to top