Search code examples
jsonapache-nifi

NiFi: EvaluateJSONPath & splitting if a JSON Object contains an object matching an attribute


Very similar question to Nifi EvaluateJsonPath by comparing with an Attribute:

I am receiving JSON like this:

{
"Resources": null,
"ResourceCategories": [
    {
        "Id": "abc",
        "ServiceId": "def",
        "IsActive": true,
        "Type": "Room",
        "Names": {
            "en-GB": "OPT-DOUBLE"
        },
        ...
    },
    {
        "Id": "hij",
        "ServiceId": "lmn",
        "IsActive": true,
        "Type": "TeamArea",
        "Names": {
            "en-GB": "King Double Room SAMPLE",
            "es-ES": "King Double Room",
            "et-EE": "King Double Room",
        },
        ...
    }
]

}

I am storing an attribute data.defaultLanguage, that can be en-GB, en-US, etc.

I tried using EvaluateJsonPath using:

$.ResourceCategories[*].Names[${data.defaultLanguage}]

but because EvaluateJsonPath doesn't support expression language this doesn't work.

What I'm trying to do is:

IF Names includes a subschema with a name that matches data.defaultLanguage, store its value as an attribute. Ignore every other object within the Names schema.

Feel like if there was some way to have all subschema within each Names schema added as an attribute name, I could get it.

Any thoughts on how I can handle this? Thank you!


Solution

  • It's possible when you pass content into an attribute and use jsonPath function

    Example (GenerateFlowFile -> ExtractText -> UpdateAttribute):

    GenerateFlowFile (input with attributes):

    • Custom text:
    {
        "Resources": null,
        "ResourceCategories": [{
                "Id": "abc",
                "ServiceId": "def",
                "IsActive": true,
                "Type": "Room",
                "Names": {
                    "en-GB": "OPT-DOUBLE"
                }
            },
            {
                "Id": "hij",
                "ServiceId": "lmn",
                "IsActive": true,
                "Type": "TeamArea",
                "Names": {
                    "en-GB": "King Double Room SAMPLE",
                    "es-ES": "King Double Room",
                    "et-EE": "King Double Room"
                }
            }
        ]
    }
    
    • data.defaultLanguage (dynamic attribute):
    en-GB
    
    • path (dynamic attribute):
    $.ResourceCategories[*].Names['PLACEHOLDER']
    

    ExtractText (content to attribute):

    • Enable DOTALL Mode: true
    • Enable Multiline Mode: true
    • Enable Unix Lines Mode: true
    • json (dynamic attribute):
    (.*)
    

    UpdateAttribute (evaluate jsonPath):

    • json-path (dynamic attribute):
    ${json:jsonPath(${path:replace("PLACEHOLDER", ${data.defaultLanguage})})}
    

    output (json-path attribute):

    ["OPT-DOUBLE","King Double Room SAMPLE"]