8

Given the following JSON I want to get the id field of the parent by an equals text compare of a sub-child element:

{
    "datapoints": [{
            "id": "default.1",
            "definedBy": "default/0.1",
            "featureValues": {
                "bui.displayname": "Health status",
                "bui.visibility": "normal",
                "default.access": "r",
                "default.basetype": "text",
                "default.description": "Aggregated health status",
                "default.format": "text/plain",
                "default.name": "health_status",
                "default.restriction": "re:(OK|WARN|ERROR|UNKNOWN)"
            }
        }, {
            "id": "kdl.240",
            "definedBy": "kdl/0.9",
            "featureValues": {
                "bui.displayname": "Delta K",
                "bui.visibility": "normal",
                "default.access": "rw",
                "default.basetype": "real",
                "default.description": "Delta K",
                "default.name": "Delta_K",
                "default.privacy": "false",
                "default.restriction": "b32"
            }
        }
    ]
}

My first goal is to get the correct data point by a sub-child text compare like:

$['datapoints'][*]['featureValues'][?(@['default.name']=='Delta_K')]

It seems not to work when I test it on http://jsonpath.com/ To get all the data points I used this successfully:

$['datapoints'][*]['featureValues']['default.name']

My goal is to get the id value of the data point with the featureValues child element default.name is equal Delta_K. In the example this would be kdl.240.

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92

4 Answers4

7

I could only solve the first part of my question by using:

$['datapoints'][*][?(@['default.name']=='Delta_K')]

During my research I found that jsonpath does not support to get the parent of a filtered node. In Chapter 7 "Conclusion" of http://www.baeldung.com/guide-to-jayway-jsonpath it's written:

Although JsonPath has some drawbacks, such as a lack of operators for reaching parent or sibling nodes, it can be highly useful in a lot of scenarios.

Also further SO posts couldn't help me.

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
2

The following code is working for me on https://jsonpath.com :

$.datapoints[?(@.featureValues['default.name']=='Delta_K')].id
Brice
  • 786
  • 4
  • 16
  • 1
    It's quite a while since I originally asked that question. It seems that this is possible with your query tested on https://jsonpath.com to get what I wanted back then. I'll set it as the correct answer. – Bruno Bieri Aug 05 '22 at 11:37
  • how will you resolve if you have one more layer of json like "name" : [ { "brand": "apple" } ], inside each department where i want to return if brand name == apple. – parlad Jul 11 '23 at 00:24
  • i provided an answer https://stackoverflow.com/a/76670888/2254425. Hope this help! – Brice Jul 12 '23 at 13:03
1

You need to find a node containing a featureValues attribute that contains a default.name attribute that matches your text. Using the suggestion at the end of https://github.com/json-path/JsonPath/issues/287 you can get what you want with:

$..[?(@.featureValues[?(@['default.name']=='Delta_K')] empty false)].id

Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
0
#cat jsonData.json | jq ‘.datapoints[].featureValues | select .default.name == 'Delta_K') | .id’

see also: https://github.com/adriank/ObjectPath/issues/70