Introducing SegQL

SegQL is a domain specific query language which purpose is to find matching objects in JSON format. It provides a way for querying data via the API. It could be used to check if specific content should be shown in a message. It could also be available as a service called from customers environment to check if json representation of profile matches certain condition.

It includes logical operators, query nesting and comparator functions.

Types

SegQL values are strictly typed, comparators accept only values of the proper type. All comparators have fixed set of accepted types.

SegQL accepts JSON primitive types:

boolean number null string

Additionally it defines following types:

date - subset of string type, date in format: YYYY-MM-DD HH:ii:ss

duration - subset of string type, duration in format Number + y/M/w/d/h/m, for example: 1d, 15M, 24h

Comparators

Comparator syntax:

"path.to.field" : {
  "comparatorType": VALUE
}

Available comparators

after
Description: checks if actual date is after passed date Accepted types: date

before
Description: checks if actual date is before passed date Accepted types: date

contains
Description: checks if string contains substring Accepted types: string, date

endsWith
Description: checks if string ends with substring Accepted types: string, date

equals
Description: strictly compares two values Accepted types: boolean, number, null, string, date

startsWith
Description: checks if string starts with substring Accepted types: string, date

youngerThan
Description: checks if date is younger than passed time duration Accepted types: duration

olderThan
Description: checks if date is older than passed time duration Accepted types: duration

matchesRegex
Description: checks if string matches provided regular expression Accepted types: string, date, duration

Shortcut for equals comparator

The equals comparator can be omitted, for example:

"foo": "bar"

means the same as:

"foo": {
  "equals": "bar"
}

Comparators negation

All comparators can be negated simply by inserting exclamation mark before the comparator name, for example:

{
  "foo": {
    "!equals": "bar"
  }
}

Special comparator - $includes

The $includes comparator changes context of the nested collections searching. Unlike ordinary comparators, it accepts logical segments, not primitive ones.

Let's assume that foo is an array of elements, without $includes operator engine will search for matching values inside every array element jointly:

{
  "foo.bar": "bar",
  "foo.baz": "baz
}

With $includes operator it will search for matching values inside every array element separately:

{
  "foo": {
    "$includes": {
      "bar": "bar",
      "baz": "baz"
    }
  }
}

Special comparators - aggregates

Aggregates allow to add more than one comparator for single field. Aggregates are similar to comparators, except that aggregates take array of comparators (without field name) or other aggregators as argument.

Comparator syntax:

"path.to.field" : {
  "aggregateType": [
    { "comparatorName": "primitiveValue" },
    { "anotherComparatorName": "primitiveValue" },
    {
      "aggregateType": [
        { "comparatorName": "primitiveValue" },
        { "anotherComparatorName": "primitiveValue" },
      ]
    }
  ]
}

Examples:

"name" : {
  "some": [
    { "equals": "john" },
    { "equals": "joe" },
    { "startsWith": "p" }
  ]
},
"address.zipCode" : {
  "some": [
    {
      "every": [
        { "startsWith": "05" },
        { "endsWith": "0" },
      ]
    },
    { "equals": "00-210" }
  ]
}

Available aggregates

some

Description: checks if any of comparators are truthy Accepted types: array of comparators and nested aggregates

every

Description: checks if all of comparators are truthy Accepted types: array of comparators nested aggregates

Logical operators

Keywords: $and, $or, $not Accepted values: comparators or other logical operators

Examples:

{
  "$and": {
    "foo: {
      "contains": "oo"
    }
  }


{
  "$or": {
    "foo": "foo",
    "bar": "bar"
  }
}


{
  "$and": {
    "$and": {
      "foo": "foo"
    },
    "$or": {
      "bar": "bar",
      "baz": "baz"
    }
  }
}

$and operator can be omitted - all standalone comparators and logical operator will be internally wrapped by $and operator, in example:

{
  "foo": {
    "equals": "foo"
  },
  "bar": {
    "startsWith": "ba"
  }
}


{
  "baz": {
    "$includes": {
      "bat": {
        "endsWith": "at"
      }
    }
  }
}


{
  "$and": {
    "foo": {
      "equals": "foo"
    }
  },
  "$or": {
    "bar": {
      "equals": "bar"
    },
    "baz": {
      "equals": "baz"
    }
  }
}

Previous Post Next Post