Painlessでの値の取得方法について

お世話になります。

以下ご質問の続きとなりますが、

requestの値について①②のパターンがあり
以下処理を実施したいです。

"request=http://aaa.com/bbb/ccc request=http://ddd.com/"(配列)
または
"request=http://aaa.com/bbb/ccc"(String型)

「http:// XXX」の XXX を抽出

XXX の値の前後に"*"を追加
"requestdomain" : ["*aaa*","*ddd*"]
"requestdomain" : "*aaa*"

②のデータについて以下処理を実装したのですが、
結果がエラーとなっています。
"error" : ""が何も出力されていないため想定となりますが、
下記太字にて値の取得の記載が間違っているのではと思われます。

def matcher = /^https?:/{2,}(.*?)(/|$)/.matcher(ctx.request);

▼ご質問
painlessにて、値の取得方法が間違っていましたら、正しい取得方法をご教示お願いします。
もし間違っていない場合、エラー原因について分かりましたら教えて頂けますと幸いです。

POST /_ingest/pipeline/_simulate
{
  "pipeline": {
    "processors": [
      {
        "kv": {
          "field": "message",
          "field_split": """\s(?![\\\[\]!"#$%&'()*+,-./:;<>?@\^`{|}~\w[^ -~。-゚] ]+?(\s+|$))""",
          "value_split": "="
        }
      },
      {
        "script": {
          "lang": "painless",
          "source": """
          if (ctx.request instanceof List){
            ctx.requestdomain = []; 
              for (line in ctx.request) {
                def matcher = /^https?:\/{2,}(.*?)(\/|$)/.matcher(line);
                 if (matcher.find()) { 
                  ctx.requestdomain.add('*' + matcher.group(1).trim() + '*'); 
                 }
              }
          } else if (ctx.request instanceof String) {
            def matcher = /^https?:\/{2,}(.*?)(\/|$)/.matcher(ctx.request);
              if (matcher.find()) {
               ctx.requestdomain.add('*' + matcher.group(1).trim() + '*');
              }
          }
            """
        }
      }
    ],
    "on_failure": [
      {
        "set": {
          "field": "_index",
          "value": "failed-index_ddi"
        }
      },
      {
        "set": {
          "field": "error",
          "value": "{{ _ingest.on_failure_message }}"
        }
      }
    ]
  },
  "docs": [
    {
      "_index": "bbb",
      "_id": "id1",
      "_source": {
        "message": "request=http://aaa.com/bbb/ccc"
      }
    }
    
  ]
}

結果

{
  "docs" : [
    {
      "doc" : {
        "_index" : "failed-index_ddi",
        "_type" : "_doc",
        "_id" : "id1",
        "_source" : {
          "request" : "http://aaa.com/bbb/ccc",
          "message" : "request=http://aaa.com/bbb/ccc",
          "error" : ""
        },
        "_ingest" : {
          "timestamp" : "2020-03-11T01:04:23.698581Z"
        }
      }
    }
  ]
}

ctx.requestdomainの宣言行を最初のif文の前にしてみてください。

        "script": {
          "lang": "painless",
          "source": """
            ctx.requestdomain = [];  // ←コレ
            if (ctx.request instanceof List){
               for (line in ctx.request) {

エラーの原因としては、最初のリストのインスタンスかどうかを判定するif文の中で
requestdomainの初期化を宣言していますが、これだとelseの中でctx.requestdomain.addと書いているところで、ctx.requestdomainがまだ宣言されてないため、addができないと想像します。

          } else if (ctx.request instanceof String) {
            def matcher = /^https?:\/{2,}(.*?)(\/|$)/.matcher(ctx.request);
              if (matcher.find()) {
               ctx.requestdomain.add('*' + matcher.group(1).trim() + '*');
              }
          }

ctx.requestdomainの宣言をelse ifに追加してもエラーが解消することから、たぶんこの想像であっていると思います。

          } else if (ctx.request instanceof String) {
            def matcher = /^https?:\/{2,}(.*?)(\/|$)/.matcher(ctx.request);
              if (matcher.find()) {
                ctx.requestdomain = [];  //←コレ
                ctx.requestdomain.add('*' + matcher.group(1).trim() + '*');
              }
          }

回答頂きありがとうございます。

初歩的なところで失敗していました…
上記実装で実現できました。

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.