Skip to content

QOBOM Query over block of maps

Boleslav Březovský edited this page Sep 24, 2018 · 3 revisions

QOBOM is simple SQL-like dialect used for doing message statistics.

DIALECT

QOBOM dialect currently consists of two basic parts that can be combined together to get statistics. First part is filtering and second optional part is counting.

FILTERING

Filtering part starts with keep keyword, followed by list of keys that should be kept with optional type of kept data. Let's break it down:

  • keep lit-word! - keep one key
  • keep block! - keep multiple keys
  • keep * - keep all keys

Only key's value is kept by default, this can be changed with as map modifier:

  • keep <key(s)> - store only value(s)
  • keep <key(s)> as map - store as map (key/value pairs)

List of keys must be followed by one or more conditions that must be fulfilled to keep the data. Conditions are preceded by where keyword.Various conditions are possible:

  • where <key> is <value> - value of <key> must be same as <value>
  • where <key> <condition> <value> - <condition> can be: >, <, >=, <=, =
  • where <key> is from block! - value of <key> must be on of values in given block
  • where <key> contains <value> - value of <key> must contain <value>
  • where <key> matches <parse rule> - value of <key> must match given parse rule

can be paren! also, in that case it's treated as Red expression and evaluated first. See examples bellow.

Multiple conditions can be chained together with and and or keywords.

COUNTING

Because the aim of QOBOM is statistic, counting is very important part of the dialect. We can for example filter messages for authors who posted in last hour. Result block may look like this:

["john" "john" "george" "paul" "paul" "john" "ringo" "john" "paul" "george" "john"]

which is not that useful. With counting, we can turn this to:

#(
    "john"   5
    "paul"   3
    "george" 2
    "ringo"  1
)

which is much more useful format. Counting is simple:

  • count - count values and return map with number of occurrences as in example above. Expects that result of keep is block of values.
  • count by <key> paren! - count together results of paren! expression and set the result to <key> value. Expects that result of keep is block of maps. Expression is bound to keys from a record.

Examples

In these examples, we will be working with block of Gitter messages, that have following structure in Gritter (in compact format):

#(
    id: "597f5fc8614889d475078f84"                                                                                        
    text: "Excellent! Thanks!"                                                                                          
    sent: 31-Jul-2017/16:50:16.664
    author: "greggirwin"                                                                                                  
    room: "red/mezz"
    room-id: "573d593ac43b8c601973bfb5"
)

Get all messages written in last day

keep * where 'sent > (now - 24:00:00)

Returns block of blocks with message values.

keep * as map where 'sent > (now - 24:00:00)

Returns block of maps with messages.

Get all authors who written in last day

keep 'author where 'sent > (now - 24:00:00)

Get all messages written by particular author

keep * as map where 'author = "rebolek"

Count messages from last day by author

keep 'author where 'sent > (now - 24:00:00) count

Count messages length from last day by author

keep * as map where 'sent > (now - 24:00:00) count by 'author (length? text)

More examples will be added as the dialect will be expanded.