2

I am trying to find a procedural way of applying the following filter. Given the following object, how can I get all top-level keys that contain child c2?

{
  "a1" : {
    "b" : {
      "c1": {},
      "c2": {}
    }
  },
  "a2" : {
    "b" : {
      "c1" : {}
    }
  },
  "a3" : {
    "b" : {
      "c1" : {},
      "c2" : {}
    }
  } 
}

Expected result:

["a1", "a3"]

I need that filter in JSONPath, JMESPath or ObjectPath syntax.

I tried countless combinations of $.*[@.b.c2] in ObjectPath, things like $..[?(b.c2)] in JSONPath, down to constructs like @.* | [?contains(keys(@), 'c2')] or @.*[b.c2] | @ in JMESPath - all to no avail.

Hubert Grzeskowiak
  • 15,137
  • 5
  • 57
  • 74

1 Answers1

4

In ObjectPath selectors work only on lists so $.*[@.b.c2] has nothing to work on. Nested objects like in your example are rare so I didn't implement a way to do what you need. You could try to transform your object to an array like following:

[
  {
    "name": "a1",
    "b": {
      "c1": {},
      "c2": {}
    }
  },
  {
    "name": "a2",
    "b": {
      "c1": {}
    }
  },
  {
    "name": "a3",
    "b": {
      "c1": {},
      "c2": {}
    }
  }
]

and then use selectors.

$.*[@.b.c2 is not null].name

PS. Use the newest ObjectPath version from Github. I fixed some issues with null comparison just a minute ago.

  • Thanks! This is what I did. My learning from this issue is: don't use data in the keys, only in values. The paths should stay the same when the contained data changes. – Hubert Grzeskowiak Dec 03 '18 at 01:43
  • This is bad learning. Object keys are unique and should be used when the uniqueness of data is important. This is rare in JSON, but this doesn't mean it is bad practice - it's just that people use JSON differently. ObjectPath should have tools for dealing with this kind of data, but because of lack of time and demand, I haven't implemented it yet. – Adrian Kalbarczyk Dec 04 '18 at 12:04
  • No worries, it's not available in JSONPath or JmesPath either :) – Hubert Grzeskowiak Dec 05 '18 at 03:11