Home > database >  JMESPath to filter on object instead of array
JMESPath to filter on object instead of array

Time:09-22

Sorry, I tried but simply cannot get my JMESPath filtering works to filter Github GraphQL for private repos.

Here is the Github GraphQL result I want to filter:

{
  "data": {
    "repositoryOwner": {
      "repositories": {
        "edges": [
          {
            "node": {
              "name": "foo",
              "isFork": false,
              "isPrivate": true,
              "createdAt": "2019-04-25T20:31:07Z",
              "updatedAt": "2019-04-30T03:44:30Z",
              "primaryLanguage": {
                "primaryLanguage": "JavaScript"
              }
            }
          },
          {
            "node": {
              "name": "bar",
              "isFork": false,
              "isPrivate": true,
              "createdAt": "2019-04-25T01:26:31Z",
              "updatedAt": "2019-04-28T23:16:03Z",
              "primaryLanguage": {
                "primaryLanguage": "JavaScript"
              }
            }
          },
          {
            "node": {
              "name": "fur",
              "isFork": false,
              "isPrivate": false,
              "createdAt": "2019-04-25T02:46:28Z",
              "updatedAt": "2019-06-12T15:46:30Z",
              "primaryLanguage": {
                "primaryLanguage": "JavaScript"
              }
            }
          },
          {
            "node": {
              "name": "blog",
              "isFork": false,
              "isPrivate": false,
              "createdAt": "2013-03-17T13:37:44Z",
              "updatedAt": "2019-06-08T02:58:44Z",
              "primaryLanguage": null
            }
          },
          {
            "node": {
              "name": "blogs",
              "isFork": false,
              "isPrivate": true,
              "createdAt": "2015-12-06T03:52:14Z",
              "updatedAt": "2016-02-27T05:17:52Z",
              "primaryLanguage": {
                "primaryLanguage": "CSS"
              }
            }
          }
        ]
      }
    }
  }
} 

I've tried

data.repositoryOwner.repositories.edges.node[?isPrivate==`true`]
data.repositoryOwner.repositories.edges[].node[?isPrivate==`true`]
data.repositoryOwner.repositories.edges[].[node[?isPrivate==`true`]]

But none of them give me the list I want, as every single example from https://jmespath.org/tutorial.html is about filtering on array elements, whereas mine above is not.

Similar situation, for

curl -s https://api.github.com/repos/golang/go/events | jp "[?type=='IssuesEvent'].payload.{Title: issue.title, URL: issue.url, User: issue.user.login, Event: action}"

How to further filter above on payload.action=='created' (in place without using pipes)?

UPDATE2:

The answer is,

[?type=='IssueCommentEvent' && payload.action=='created'].payload.{Title: issue.title, URL: issue.url, User: issue.user.login, Event: action}

and we'll get:

[
  {
    "Title": "x/website: post https://go.dev/blog/tidy-web contains a broken link",
    "URL": "https://api.github.com/repos/golang/go/issues/47975",
    "User": "ilikegolang",
    "Event": "created"
  },
  {
    "Title": "cmd/compile: pointer to concrete type doesn't satisfy generic type method set",
    "URL": "https://api.github.com/repos/golang/go/issues/48512",
    "User": "DmitriyMV",
    "Event": "created"
  },
  {
    "Title": "How to solve this problem, run gomobile bind-target = android to report an error ",
    "URL": "https://api.github.com/repos/golang/go/issues/48510",
    "User": "ytxyyt",
    "Event": "created"
  },
. . .
]

Please help.

UPDATE:

I asked, "as every single example from https://jmespath.org/tutorial.html is about filtering on array elements, whereas mine above is not", and got:

In order to filter, you will need an array.

However, that's not what I'm expecting, as using the first one as the example, I'm expecting the filtered to be a JSON array:

[
      {
          "name": "foo",
          "isFork": false,
          "isPrivate": true,
          "createdAt": "2019-04-25T20:31:07Z",
          "updatedAt": "2019-04-30T03:44:30Z",
          "primaryLanguage": {
            "primaryLanguage": "JavaScript"
      },
      {
          "name": "bar",
          "isFork": false,
          "isPrivate": true,
          "createdAt": "2019-04-25T01:26:31Z",
          "updatedAt": "2019-04-28T23:16:03Z",
          "primaryLanguage": {
            "primaryLanguage": "JavaScript"
      },
      {
          "name": "blogs",
          "isFork": false,
          "isPrivate": true,
          "createdAt": "2015-12-06T03:52:14Z",
          "updatedAt": "2016-02-27T05:17:52Z",
          "primaryLanguage": {
            "primaryLanguage": "CSS"
      }
    ]

I can accept "no way" as the answer, but that seems to be a serious design flaw, as JsonPath can easily do that.

CodePudding user response:

Your filtering have to happen on the edges array, still, the property you evaluate can be nested deeper in the object.
So you can perfectly have a condition like node.isPrivate == `true`, or even simpler, since node.isPrivate is already a boolean, a condition that would simply read node.isPrivate.

Given the query:

data.repositoryOwner.repositories.edges[?node.isPrivate].node

We end up with the expect JSON:

[
  {
    "name": "foo",
    "isFork": false,
    "isPrivate": true,
    "createdAt": "2019-04-25T20:31:07Z",
    "updatedAt": "2019-04-30T03:44:30Z",
    "primaryLanguage": {
      "primaryLanguage": "JavaScript"
    }
  },
  {
    "name": "bar",
    "isFork": false,
    "isPrivate": true,
    "createdAt": "2019-04-25T01:26:31Z",
    "updatedAt": "2019-04-28T23:16:03Z",
    "primaryLanguage": {
      "primaryLanguage": "JavaScript"
    }
  },
  {
    "name": "blogs",
    "isFork": false,
    "isPrivate": true,
    "createdAt": "2015-12-06T03:52:14Z",
    "updatedAt": "2016-02-27T05:17:52Z",
    "primaryLanguage": {
      "primaryLanguage": "CSS"
    }
  }
]
  • Related