Convert jsonlogic data into tree structure - data-structures

I have jsonlogic data as shown below. I'm trying to convert it into a abstract syntax tree structure using Ruby. What I'm interested in is the leaf nodes that has key of "var" and trying to establish relationship on which leaf node belongs to which node. For example, node ending with "var": ".name" is related to "var": "self.product_variations.all". Is there other ways to achieve it?
{
"map": [{
"var": "self.product_variations.all"
}, {
"map": [{
"filter": [{
"var": ".child.categories.all"
}, {
"==": [{
"var": ".category_set.name"
}, "Mens"]
}]
}, {
"var": ".name"
}]
}]
}

Related

Get the path of a jsonata match

I'm using jsonata to query a json file that I have. I have a query that returns an array of results with the value from each match. What I also want to know is what is the exact path to my match.
Example:
Suppose I had the following JSON
"files": [
{
"name": "file_1",
"type": "txt"
},
{
"name": "file_2",
"type": "csv"
},
{
"name": "file_3",
"type": "txt"
}
]
}
and I had the following query:
files[type="txt"].name
I would like to know both the value of my query results and the path of all hits. E.g:
[
{value: "file_1", path: "files[0].name"},
{value: "file_3", path: "files[2].name"}
]
Is this something that is possible?
I do not think JSONata has such feature. But there could be another way to achieve what you are looking for.
If you are interested in the index value, there is a built-in operator is JSONata - Positonal Variable Binding operator.
And if you're interested in knowing the parent of a given search, you could use the Parent operator.
Here's a practical example that builds on #anindya-dey's answer. Maybe it's all you need, maybe not.
Input json
{
"files": [
{
"name": "file_1",
"type": "txt"
},
{
"name": "file_2",
"type": "csv"
},
{
"name": "file_3",
"type": "txt"
}
]
}
Jsonata expression
files#$i[type="txt"].{
'value': name,
'path': 'files[' & $i & '].name'
}
Result
[
{
"value": "file_1",
"path": "files[0].name"
},
{
"value": "file_3",
"path": "files[2].name"
}
]

How to use JSONpath to extract specific values

I'm using JSONpath to try and find data with an array of JSON objects but I'm struggling to get to the information I want. The array contains many objects similar to below where there are values for RecID throughout. If I use $..RecID I get them all when I only want the first Key.RecID of each object (with a value 1338438 in this example). Is there a way to only extract the top level Key.RecID value?
BTW I'm trying to do this in jMeter and I'm assuming JSONpath is the best way to do what I want but if there is a better way I'd be happy to hear about it.
Thanks in advance
[{
"Key": {
"RecID": 1338438
},
"Users": [{
"FullName": "Miss Burns",
"Users": {
"Key": {
"Name": "Burns",
"RecID": 1317474
}
}
},
{
"FullName": "Mrs Fisher",
"Users": {
"Key": {
"Name": "Fisher",
"RecID": 1317904
}
}
}
],
"User": {
"FullName": "Mrs Fisher",
"Key": {
"Name": "Fisher",
"RecID": 1317904
}
},
"Organisation": {
"Key": {
"RecID": 1313881
}
}
}]

Incorrectly selected data in the query

Only articles that contain the EmailMarketing tag are needed.
I'm probably doing the wrong search on the tag, since it's an array of values, not a single object, but I don't know how to do it right, I'm just learning graphql. Any help would be appreciated
query:
query {
enArticles {
title
previewText
tags(where: {name: "EmailMarketing"}){
name
}
}
}
result:
{
"data": {
"enArticles": [
{
"title": "title1",
"previewText": "previewText1",
"tags": [
{
"name": "EmailMarketing"
},
{
"name": "Personalization"
},
{
"name": "Advertising_campaign"
}
]
},
{
"title": "title2",
"previewText": "previewText2",
"tags": [
{
"name": "Marketing_strategy"
},
{
"name": "Marketing"
},
{
"name": "Marketing_campaign"
}
]
},
{
"title": "article 12",
"previewText": "article12",
"tags": []
}
]
}
}
I believe you first need to have coded an equality operator within your GraphQL schema. There's a good explanation of that here.
Once you add an equality operator - say, for example _eq - you can use it something like this:
query {
enArticles {
title
previewText
tags(where: {name: {_eq: "EmailMarketing"}}){
name
}
}
}
Specifically, you would need to create a filter and resolver.
The example here may help.

JoltTransformJson: Transform JSON Array with and add static value to each item from a FlowFile attribute

I need to transform a JSON response from one time-series DB and output it to as a response in a new format.
Having an input JSON array, I need to transform it with JoltTransformJson (NiFi) and add a key-value for each item from a FlowFile attribute.
This is my input JSON:
{
"Items": [
{
"Timestamp": "2020-04-29T07:46:20.558731Z",
"Value": 66.0303
},
{
"Timestamp": "2020-04-29T07:46:35.558731Z",
"Value": 69.11584
}
]
}
The desired output should be:
[{
"sensor_id": "xyz",
"sample_time": "2020-04-29T07:46:20.558731Z",
"sample_value": 66.0303
}, {
"sensor_id": "xyz",
"sample_time": "2020-04-29T07:46:35.558731Z",
"sample_value": 69.11584
}]
where sensor_id is a FlowFile attribute...
I came across to this spec:
[{
"operation": "shift",
"spec": {
"Items": {
"*": {
"#Timestamp": "[#2].sample_time",
"#Value": "[#2].sample_value",
"${sensor_id}": "[#2].sensor_id"
}
}
}
}]
But I cannot get the sensor_id in the output json.... instead, this is what I get:
[{
"sample_time": "2020-04-29T07:46:20.558731Z",
"sample_value": 66.0303
}, {
"sample_time": "2020-04-29T07:46:35.558731Z",
"sample_value": 69.11584
}]
Finally I've managed to project the ${sensor_id} into the output json, what was missing is #, so the final spec will be:
[{
"operation": "shift",
"spec": {
"Items": {
"*": {
"#Timestamp": "[#2].sample_time",
"#Value": "[#2].sample_value",
"#${sensor_id}": "[#2].sensor_id"
}
}
}
}]
Now, I've found that the Timestamp returned from my time-series DB is not exact what I need it to be. Instead I would like to convert it to integer timestamp (epoch sinse 1970)... Any idea how this can be achieved?

How to filter GraphQL results by a descendent without edges?

I just started looking at GraphQL and I am wondering if there is a way to filter results that don't have any nodes. Here is a relatively simple example query:
query {
organization(login:"GitHub") {
repositories(first: 20) {
edges {
node {
name
pullRequests(first: 5, states: OPEN){
edges {
node {
title
author{
login
}
updatedAt
}
}
}
}
}
}
}
}
and here is a subset of the results that query returns:
{
"data": {
"organization": {
"repositories": {
"edges": [
{
"node": {
"name": "gitignore",
"pullRequests": {
"edges": [
{
"node": {
"title": "Create new CodeComposerStudio.gitignore",
"author": {
"login": "wolf99"
},
"updatedAt": "2017-07-26T20:31:53Z"
}
},
{
"node": {
"title": "Create PVS.gitignore",
"author": {
"login": "cesaramh"
},
"updatedAt": "2017-05-01T19:42:07Z"
}
},
{
"node": {
"title": "gitignore for Magic Software Enterprises product xpa ",
"author": {
"login": "tommes"
},
"updatedAt": "2017-05-01T19:41:53Z"
}
},
{
"node": {
"title": "Create PSoC.gitignore",
"author": {
"login": "dbrwn"
},
"updatedAt": "2017-05-01T19:41:39Z"
}
},
{
"node": {
"title": "add ThinkPHP gitignore file",
"author": {
"login": "swumao"
},
"updatedAt": "2017-05-01T19:40:53Z"
}
}
]
}
}
},
{
"node": {
"name": "dmca",
"pullRequests": {
"edges": []
}
}
}
]
}
}
}
}
So I'd like to know if there is a way to modify my query so that it would not return the node named dmca since there are no edges on pullRequests.
If you are using githubs graphql api than it seems that there is no way to filter those edges,
But if you're implementing the graphql server then it's possible to know what the edges nodes are and thus filter it in the edge resolver
According to GitHub repositories documentation does not allow that kind of filtering.
first: Int
Returns the first n elements from the list.
after: String
Returns the elements in the list that come after the specified cursor.
last: Int
Returns the last n elements from the list.
before: String
Returns the elements in the list that come before the specified cursor.
privacy: RepositoryPrivacy
If non-null, filters repositories according to privacy
orderBy: RepositoryOrder
Ordering options for repositories returned from the connection
affiliations: [RepositoryAffiliation]
Affiliation options for repositories returned from the connection
isLocked: Boolean
If non-null, filters repositories according to whether they have been locked
isFork: Boolean
If non-null, filters repositories according to whether they are forks of another repository
So I don't think that can be done.

Resources