简体   繁体   English

如何在 NiFi ExecuteScript (ECMAScript) 中找到数组元素?

[英]How do I find an element of an array in NiFi ExecuteScript (ECMAScript)?

I have a need to get data out of a NiFi flow file with somewhat complex JSON content.我需要从 JSON 内容有些复杂的 NiFi 流文件中获取数据。 I'm planning to use a NiFi ExecuteScript processor because I don't think it can be done with EvaluateJSONPath .我打算使用 NiFi ExecuteScript处理器,因为我认为它不能用EvaluateJSONPath来完成。 The content looks like this (snippet)内容看起来像这样(片段)

...
"segments": [
                {
                    "INS01": "Y",
                    "INS03": "001",
                    "INS02": "18",
                    "INS05": "A",
                    "id": "INS",
                    "INS04": "AI",
                    "INS08": "FT"
                },
                {
                    "REF02": "1041558xxxxx",
                    "REF01": "0F",
                    "id": "REF"
                },
                {
                    "REF02": "ABD",
                    "REF01": "1L",
                    "id": "REF"
                },
                {
                    "REF02": "106835xxxxx",
                    "REF01": "23",
                    "id": "REF"
                }
           ],
...

I want to extract the REF02 property value from the segments array element that has REF01 === '0F' .我想从具有REF01 === '0F'的段数组元素中提取REF02属性值。 The array element does not necessarily have a REF02 property.数组元素不一定具有REF02属性。 So in the above case I should get 1041558xxxxx .所以在上面的例子中我应该得到1041558xxxxx

Here's my current script:这是我当前的脚本:

var flowFile = session.get()
if (flowFile != null) {
    var InputStreamCallback = Java.type('org.apache.nifi.processor.io.InputStreamCallback')
    var IOUtils = Java.type('org.apache.commons.io.IOUtils')
    var StandardCharsets = Java.type('java.nio.charset.StandardCharsets')
    try {
        var subscriber = null
        session.read(flowFile,
            new InputStreamCallback(function (inputStream) {
                var data = JSON.parse(IOUtils.toString(inputStream, StandardCharsets.UTF_8))
                var segment = data.segments.find(function (s) { return s.hasOwnProperty('REF01') && s.REF01 === '0F' })
                subscriber = segment ? segment.REF02 : null
            }));
        session.putAttribute(flowFile, 'subscriber', subscriber ? subscriber : '')
        session.transfer(flowFile, REL_SUCCESS)
    } catch (e) {
        log.error('script failed', e)
        session.transfer(flowFile, REL_FAILURE)
    }
}

When I execute the above, I get a java.lang.NoSuchMethodException .当我执行上面的代码时,我得到一个java.lang.NoSuchMethodException Also, are anonymous 'arrow' functions allow?另外,是否允许匿名“箭头”功能?

I've tried using an old-school for loop to no avail.我试过使用老式的for循环无济于事。

Thanks for your help.感谢您的帮助。

You can add a JoltTransformJSON processor with specification您可以添加具有规范的JoltTransformJSON处理器

[
  {
    "operation": "shift",
    "spec": {
      "segments": {
        "*": {
          "REF01": {
            "0F": {// conditional to match "REF01" with "0F" 
              "@2,REF02": ""// go two levels up the three to reach the level of the attributes REF01 or REF02   
            }
          }
        }
      }
    }
  }
]

in order to return the result为了返回结果

"1041558xxxxx"

Groovy script : Groovy 脚本

import org.apache.commons.io.IOUtils
import java.nio.charset.StandardCharsets
import groovy.json.JsonSlurper 

flowFile = session.get()
if(!flowFile) return

def jsonSlurper = new JsonSlurper()
def subscriber = ""

flowFile = session.write(flowFile, {inputStream, outputStream ->
  input = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
  json = jsonSlurper.parseText(input)
  segment = json.segments.find{ segment -> 
    if (segment.keySet().contains('REF01')) { 
      if (segment.REF01 == '0F') { 
        return true 
      } else { 
        return false
      } 
    } else {
      return false
    }
  }
  if (segment) {
    subscriber = segment.REF02
  }
  outputStream.write(input.getBytes(StandardCharsets.UTF_8))
} as StreamCallback)

session.putAttribute(flowFile, 'subscriber', subscriber)
session.transfer(flowFile, REL_SUCCESS)

input :输入

{
"test": "best",
"segments": [
                {
                    "INS01": "Y",
                    "INS03": "001",
                    "INS02": "18",
                    "INS05": "A",
                    "id": "INS",
                    "INS04": "AI",
                    "INS08": "FT"
                },
                {
                    "REF02": "1041558xxxxx",
                    "REF01": "0F",
                    "id": "REF"
                },
                {
                    "REF02": "ABD",
                    "REF01": "1L",
                    "id": "REF"
                },
                {
                    "REF02": "106835xxxxx",
                    "REF01": "23",
                    "id": "REF"
                }
           ]
}

output (with attribute subscriber : 1041558xxxxx ): output (属性subscriber1041558xxxxx ):

{
"test": "best",
"segments": [
                {
                    "INS01": "Y",
                    "INS03": "001",
                    "INS02": "18",
                    "INS05": "A",
                    "id": "INS",
                    "INS04": "AI",
                    "INS08": "FT"
                },
                {
                    "REF02": "1041558xxxxx",
                    "REF01": "0F",
                    "id": "REF"
                },
                {
                    "REF02": "ABD",
                    "REF01": "1L",
                    "id": "REF"
                },
                {
                    "REF02": "106835xxxxx",
                    "REF01": "23",
                    "id": "REF"
                }
           ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM