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

**URL:** <https://discuss.elastic.co/t/painless/223034>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [March 11, 2020, 1:12am UTC](https://discuss.elastic.co/t/painless/223034 "2020-03-11T01:12:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![harue](https://avatars.discourse-cdn.com/v4/letter/h/82dd89/32.png) [@harue](https://discuss.elastic.co/u/harue)\
**Post date:** [March 11, 2020, 1:12am UTC](https://discuss.elastic.co/t/painless/223034/1 "2020-03-11T01:12:28Z")

</div>

お世話になります。

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

> [@Ingestnode Grokにてarraylistの処理について](https://discuss.elastic.co/t/ingestnode-grok-arraylist/222390):
>
> お世話になります。 ingest nodeのGrok processorにて、配列の値を処理したいのですがエラーになります。 POST /\_ingest/pipeline/\_simulate { "pipeline": { "processors": [{ "kv": { "field": "message", "field\_split": """\s(?![\\\[\]!"#$%&'()\*+,-./:;\<\>?@\^`{|}~\w[^ -~｡-ﾟ] ]+?(\s+|$))""", "value\_split": "=" } }, { "grok": { "field": "request", "patterns": ["%{GREEDYDATA}://%{USERNAME:requestdomain}/%{GREEDYDATA}"], …

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"
        }
      }
    }
  ]
}

```

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [March 11, 2020, 2:28am UTC](https://discuss.elastic.co/t/painless/223034/2 "2020-03-11T02:28:43Z")

</div>

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

```json
        "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ができないと想像します。

```auto
          } 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に追加してもエラーが解消することから、たぶんこの想像であっていると思います。

```auto
          } 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() + '*');
              }
          }

```

---

<div class="post-metadata">

**Author:** ![harue](https://avatars.discourse-cdn.com/v4/letter/h/82dd89/32.png) [@harue](https://discuss.elastic.co/u/harue)\
**Post date:** [March 11, 2020, 2:50am UTC](https://discuss.elastic.co/t/painless/223034/3 "2020-03-11T02:50:02Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 8, 2020, 2:50am UTC](https://discuss.elastic.co/t/painless/223034/4 "2020-04-08T02:50:14Z")

</div>

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