Facet JSON Structure


The overall structure of filters is as follows. Each facet term combines a data source and constraint spec, and so all combinations of constraint kind and data source path are possible in the syntax.

<FILTERS>:  { <logical-operator>: <TERMSET> }

<TERMSET>: '[' <TERM> [, <TERM>]* ']'

<TERM>:     { <logical-operator>: <TERMSET> }
            { "source": <data-source>, <constraint(s)>, <extra-properties(s)> }
            { "sourcekey": <source-key>, <constraint(s)>, <extra-properties(s)> }

In the following sections each of location operators, data source, constraints, and extra properties are explained. You can also find some examples at the end of this document.

Logical operators

We want the structure to be as general as possible, so we don’t need to redesign the whole structure when we need to support more complex queries. Therefore as the top level, we have logical operators.

{ "and": [ term... ] }
{ "or": [ term... ]}
{ "not": term }

The current implementation of faceting in Chaise only supports and. The rest of logical operators are currently not supported.

Source path

Source path captures the source of filter. It can either be

  • one of current table’s column.
  • a column in a table that has a valid foreign key relationship with the current table.

Even if we are faceting on a vocabulary concept and just want the user to pick values by displayed row name and we substitute the actual entity keys in the ERMrest query, we must record this column choice explicitly in the facet spec so that the resulting faceting app URL is unambiguous even if there have been subtle model changes in the interim, which might change the default key selection heuristics etc.

Based on this, we are not supporting filtering on foreign keys with composite keys.

For more information about source path refer to column directive’s documentation in here.

Source key

Instead of defining a new source, you can refer to the sources that are defined in 2019:source-definitions by using sourcekey attribute. For instance, assuming path_to_table_1 is a valid source definition, you can do

{"sourcekey": "path_to_table_1"}


There are three kinds of constraint right now:

  1. Discrete choice e.g. maps to a checklist or similar UX
  2. Half-open or closed intervals, e.g. maps to a slider or similar UX
  3. Substring search, e.g. maps to a search box UX
  4. Match any record with value (not-null).

Conceptually, this should correspond to three possible syntactic forms:

{"choices": [ value, ... ]}
{"ranges": [ {"min": lower, "max": upper}, ...]}
{"search": [ "box content" ]}
{"not_null": true}

A half-open range might be {"min" lower} or {"max": upper}. By default both min and max are inclusive. To use exclusive ranges you can use min_exclusive:true or max_exclusive: true.

Extra properties

entity v.s. scalar facet

If the facet can be treated as entity (the column that is being used for facet is key of the table), setting entity attribute to false will force the facet to show scalar mode.

"entity": false