Introduction

At Motto we realized that our APIs expose a number of endpoints that need support for filters of varying complexity. For example, in our content-delivery API you may wish to retrieve all events between two dates, where the event status is either scheduled or started, where the event is a football match with at least 500 views, and where the home-team has at least two Spanish players on the team.

To support such advanced filtering, we decided that many (though not all) of our list endpoints should expose a filter parameter, which expects a KQL query. The following section details how to construct such a query.

Each Motto service determines which subset of the KQL specification it needs to support, and which fields you are allowed to query on. We recommend reading the docstrings of the API carefully, and validating that the result-sets match your expectations.

KQL implementation

The Kibana Query Language was developed with Elastic Search in mind, and while we do not use this directly in combination with Elastic Search, we still believe this DSL is intuitive and easy to write for most technical users.

Basic queries

Most of the Studio API endpoints support only the “basic” types of queries detailed in this section.

To query a single field and match against an exact term, use the following syntax:

email:john@example.com

To query two fields and match both against exact terms, you can separate the conditions by a space.

first_name:John last_name:Doe

If your term itself contains a space, you may use quotation marks. If you prefer using AND explicitly, that is supported, too.

first_name:"John Allen" AND last_name:Doe

If the filter is passed a URL parameter, make sure to URL-encode queries like the one above.

If you want to query on a range, use any of the four range operators (<, <=, >, >=):

age>=21

In the case of closed ranges, a single field may be queried twice:

date>=2023-06-01T22:00:00.00Z AND date<2024-07-02T23:10:20.00Z

Advanced queries

Besides the operators and functionality listed in the section above, some services may support more advanced filters.

To query two fields where only a single match is needed, use the following syntax:

user_id:42 OR username:john

To query a single field where multiple terms are matchable:

status:(paid OR processing)

To query a nested structure on multiple properties:

team:{name:"FC Barcelona" color:"#FFFF00"}

Some services support wildcards in query terms. This is typically on specific fields, and typically only as prefix-matches (meaning that the wildcard * needs to be the trailing character):

email:john@example.c*

The following characters must be escaped if they are part of the actual query term: \ ( ) : < > " *

To query a field with negation:

NOT user_id:42

To query with more complex and/or nested conditions:

(
    competition_id:123 AND
    (season:fall OR start_date=2023-08-01) AND
    team_id:456
) OR status:finished