メッセージのマッチングパターン

概要

Droonga Engineはメッセージのパターンを指定するための小規模な言語を実装しています。これをマッチングパターンと呼びます。 マッチングパターンは、プラグインなどの様々な場所で処理対象のメッセージを指定するために使われます。

単純なマッチング

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

これは以下のようなメッセージにマッチします:

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

深い位置にある対象へのマッチング

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

これは以下のようなメッセージにマッチします:

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

以下にはマッチしません:

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

パターン自体のネスト

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

これは以下の両方にマッチします:

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

および:

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

書式

マッチングパターンには「基本パターン」と「ネストしたパターン」の2種類があります。

基本パターン

構造

基本パターンは以下のように、2つ以上の要素を含む配列として表現されます:

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

ターゲットパス

ターゲットパスは以下の文字列のような形で示します:

"body.success"

Droonga Engineのマッチング機構は、これをドットで区切られた パスコンポーネント のリストとして解釈します。 1つのパスコンポーネントはメッセージ中の同名のプロパティを表します。 よって、上記の例は以下の位置を示します:

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

利用可能な演算子

演算子はシンボルとして指定します。

:equal
ターゲットの値が与えられた値と等しい場合に true を返します。それ以外の場合は false を返します。 例えば、
["type", :equal, "search"]

上記のパターンは以下のようなメッセージにマッチします:

{
  "type": "search",
  ...
}
:in
ターゲットの値が与えられた配列の中に含まれている場合に true を返します。それ以外の場合は false を返します。 例えば、
["type", :in, ["search", "select"]]

上記のパターンは以下のようなメッセージにマッチします:

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

以下にはマッチしません:

{
  "type": "find",
  ...
}
:include
ターゲットの値の配列の中に指定された値が含まれている場合に true を返します。それ以外の場合は false を返します。 言い換えると、これは :in 演算子の反対の働きをします。 例えば、
["body.tags", :include, "News"]

上記のパターンは以下のようなメッセージにマッチします:

{
  "type": "my.notification",
  "body": {
    "tags": ["News", "Groonga", "Droonga", "Fluentd"]
  }
}
:exist
ターゲットに指定された情報が存在する場合は true を返します。それ以外の場合は false を返します。 例えば、
["body.comments", :exist, "News"]

上記のパターンは以下のようなメッセージにマッチします:

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

以下にはマッチしません:

{
  "type": "my.notification",
  "body": {
    "title": "Hello!"
  }
}
:start_with
ターゲットの文字列が指定された文字列で始まる場合に true を返します。それ以外の場合は false を返します。 例えば、
["body.path", :start_with, "/archive/"]

上記のパターンは以下のようなメッセージにマッチします:

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

ネストしたパターン

構造

ネストしたパターンは、以下のような3つの要素を持つ配列として表現されます:

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

利用可能な演算子

:and
与えられた両方のパターンが true を返す場合に、true を返します。それ以外の場合は false を返します。
:or
与えられたパターン(1番目または3番目の要素)のいずれかまたは両方が true を返す場合に true を返します。それ以外の場合は false を返します。