Matching pattern for messages

Abstract

The Droonga Engine provides a tiny language to specify patterns of messages, called matching pattern. It is used to specify target messages of various operations, ex. plugins.

Examples

Simple matching

pattern = ["type", :equal, "search"]

This matches to messages like:

{
  "type": "search",
  ...
}

Matching for a deep target

pattern = ["body.success", :equal, true]

This matches to messages like:

{
  "type": "add.result",
  "body": {
    "success": true
  }
}

Doesn’t match to:

{
  "type": "add.result",
  "body": {
    "success": false
  }
}

Nested patterns

pattern = [
             ["type", :equal, "table_create"],
             :or,
             ["body.success", :equal, true]
          ]

This matches to both:

{
  "type": "table_create",
  ...
}

and:

{
  "type": "column_create",
  ...
  "body": {
    "success": true
  }
}

Syntax

There are two typeos of matching patterns: “basic pattern” and “nested pattern”.

Basic pattern

Structure

A basic pattern is described as an array including 2 or more elements, like following:

["type", :equal, "search"]

Target path

The target path is specified as a string, like:

"body.success"

The matching mechanism of the Droonga Engine interprets it as a dot-separated list of path components. A path component represents the property in the message with same name. So, the example above means the location:

{
  "body": {
    "success": <target>
  }
}

Avialable operators

The operator is specified as a symbol.

:equal
Returns true, if the target value is equal to the given value. Otherwise false. For example,
["type", :equal, "search"]

The pattern above matches to a message like following:

{
  "type": "search",
  ...
}
:in
Returns true, if the target value is in the given array of values. Otherwise false. For example,
["type", :in, ["search", "select"]]

The pattern above matches to a message like following:

{
  "type": "select",
  ...
}

But it doesn’t match to:

{
  "type": "find",
  ...
}
:include
Returns true if the target array of values includes the given value. Otherwise false. In other words, this is the opposite of the :in operator. For example,
["body.tags", :include, "News"]

The pattern above matches to a message like following:

{
  "type": "my.notification",
  "body": {
    "tags": ["News", "Groonga", "Droonga", "Fluentd"]
  }
}
:exist
Returns true if the target exists. Otherwise false. For example,
["body.comments", :exist, "News"]

The pattern above matches to a message like following:

{
  "type": "my.notification",
  "body": {
    "title": "Hello!",
    "comments": []
  }
}

But it doesn’t match to:

{
  "type": "my.notification",
  "body": {
    "title": "Hello!"
  }
}
:start_with
Returns true if the target string value starts with the given string. Otherwise false. For example,
["body.path", :start_with, "/archive/"]

The pattern above matches to a message like following:

{
  "type": "my.notification",
  "body": {
    "path": "/archive/2014/02/28.html"
  }
}

Nested pattern

Structure

A nested pattern is described as an array including 3 elements, like following:

[
  ["type", :equal, "table_create"],
  :or,
  ["type", :equal, "column_create"]
]

Avialable operators

:and
Returns true if both given patterns are evaluated as true. Otherwise false.
:or
Returns true if one of given patterns (the first or the third element) is evaluated as true. Otherwise false.