How to get entire parent node using jq json parser? - json

I am trying to find a value in the json file and based on that I need to get the entire json data instead of that particular block.
Here is my sample json
[{
"name" : "Redirect to Website 1",
"behaviors" : [ {
"name" : "redirect",
"options" : {
"mobileDefaultChoice" : "DEFAULT",
"destinationProtocol" : "HTTPS",
"destinationHostname" : "SAME_AS_REQUEST",
"responseCode" : 302
}
} ],
"criteria" : [ {
"name" : "requestProtocol",
"options" : {
"value" : "HTTP"
}
} ],
"criteriaMustSatisfy" : "all"
},
{
"name" : "Redirect to Website 2",
"behaviors" : [ {
"name" : "redirect",
"options" : {
"mobileDefaultChoice" : "DEFAULT",
"destinationProtocol" : "HTTPS",
"destinationHostname" : "SAME_AS_REQUEST",
"responseCode" : 301
}
} ],
"criteria" : [ {
"name" : "contentType",
"options" : {
"matchOperator" : "IS_ONE_OF",
"values" : [ "text/html*", "text/css*", "application/x-javascript*" ],
}
} ],
"criteriaMustSatisfy" : "all"
}]
I am trying to match for "name" : "redirect" inside each behaviors array and if it matches then I need the entire block including the "criteria" section, as you can see its under same block {}
I managed to find the values using select methods but not able to get the parent section.
https://jqplay.org/s/BWJwVdO3Zv
Any help is much appreciated!

To avoid unwanted duplication:
.[]
| first(select(.behaviors[].name == "redirect"))
Equivalently:
.[]
| select(any(.behaviors[]; .name == "redirect"))

You can try this jq command:
<file jq 'select(.[].behaviors[].name=="redirect")'

Related

Json schema validation : required attributes based on attributes from different object in same json

I have a requirement where i need to define attribute in one object as required based on value of attribute in another object.
e.g
{
"if" : {
"properties" : {
"Status" : {
"const" : "CANCELLED"
}
},
"required" : [
"Status"
]
},
"then" : {
"required" : [
"Reason"
]
}
}
above condition works. However below e.g doesn't work
{
"if" : {
"properties" : {
"#/Details/HasAgreement" : {
"const" : true
}
},
"required" : [
"#/Details/HasAgreement"
]
},
"then" : {
"required" : [
"#/Contract/EffectiveDate"
]
}
}
I'm guessing that the way how I'm referring attributes from different objects in same json is wrong. what is the right way?
Thanks,
Madhu

Parse and Map 2 Arrays with jq

I am working with a JSON file similar to the one below:
{ "Response" : {
"TimeUnit" : [ 1576126800000 ],
"metaData" : {
"errors" : [ ],
"notices" : [ "query served by:1"]
},
"stats" : {
"data" : [ {
"identifier" : {
"names" : [ "apiproxy", "response_status_code", "target_response_code", "target_ip" ],
"values" : [ "IO", "502", "502", "7.1.143.6" ]
},
"metric" : [ {
"env" : "dev",
"name" : "sum(message_count)",
"values" : [ 0.0]
} ]
} ]
} } }
My object is to display a mapping of the identifier and values like :
apiproxy=IO
response_status_code=502
target_response_code=502
target_ip=7.1.143.6
I have been able to parse both names and values with
.[].stats.data[] | (.identifier.names[]) and .[].stats.data[] | (.identifier.values[])
but I need help with the jq way to map the values.
The whole thing can be done in jq using the -r command-line option:
.[].stats.data[]
| [.identifier.names, .identifier.values]
| transpose[]
| "\(.[0])=\(.[1])"

jq : mapping array in object to another object while keeping parent keys and adding new ones

I would like to map the following structure
{
"id" : "OUTER_ID",
"name" : "OUTER_NAME"
"items" : [
{
"id" : "INNER_ID_1",
"name" : "INNER_NAME_1",
},
{
"id" : "INNER_ID_2",
"name" : "INNER_NAME_2",
}
]
}
into this
{
"payload": [
{
"key" : "INNER_NAME_1_KEY",
"data" : {
"id" : "OUTER_ID",
"name" : "OUTER_NAME",
"items" : [
{
"id" : "INNER_ID_1",
"name" : "INNER_NAME_1"
}
]
}
},
{
"key" : "INNER_NAME_2_KEY",
"data" : {
"id" : "OUTER_ID",
"name" : "OUTER_NAME",
"items" : [
{
"id" : "INNER_ID_2",
"name" : "INNER_NAME_2"
}
]
}
}
]
}
So, for each item in the initial items array, I want to create an entry in the output's payload, i.e I want to map items[i] to payload[i].data.items while also creating the payload, key and data keys in the output, and setting payload[i].data.id and payload[i].data.name to the input's outer id and name.
Can this be done with jq?
Sure, you can use the following filter :
.id as $id | .name as $name | {payload : [ .items[] | {key:.id, data:{id:$id, name: $name, items:[.]}} ] }
You can try it here.

How can extract the filename from the below JSON data

I am new to jq and not sure how to go about extracting just the filenames from the below JSON file.
{
"files" : [ {
"name" : "filename1.gz",
"StartDate" : "2018-07-09T11:00:00-04:00",
"EndDate" : "2018-07-09T12:00:00-04:00"
}, {
"name" : "filename2.gz",
"StartDate" : "2018-07-09T10:00:00-04:00",
"EndDate" : "2018-07-09T11:00:00-04:00"
}, {
"name" : "filename3.gz",
"StartDate" : "2018-07-09T09:00:00-04:00",
"EndDate" : "2018-07-09T10:00:00-04:00"
}, {
"name" : "filename4.gz",
"StartDate" : "2018-07-09T07:00:00-04:00",
"EndDate" : "2018-07-09T08:00:00-04:00"
} ]
}
expected output:
[filename1.gz,filename2.gz,filename3.gz,filename4.gz]
I see #Abdou has already given solution to this, just adding in another minified version to achieve the desired solution.
jq --compact-output '[.files[].name]'

MongoDB aggregate and count json paths

I have a MongoDB Collection which contains data elements like this:
{
"_id" : "9878jr23geg",
"element" : {
"name" : "element7",
"Set" : [
{
"SubListA" : [
{
"name" : "AlbertEinstein",
"value" : "45"
},
{
"name" : "JohnDoe",
"value" : "34"
},
]
},
{
"MoreNames" : [
{
"name" : "TimMcGraw",
"value" : "39"
}
]
}
]
}
{
"_id" : "275678hfvd",
"element" : {
"name" : "element8",
"Set" : [
{
"SubListA" : [
{
"name" : "AlbertEinstein",
"value" : "45"
},
{
"name" : "JimmyKimmel",
"value" : "41"
}
]
}
]
}
I'm trying to count the occurrences of each unique name, grouped by the element of Set to which they belong. For example, both objects in my example above have an object with name: "AlbertEinstein" inside element.Set.SublistA; therefore I'd expect a return value something along the lines of:
element.Set.SublistA.AlbertEinstein | 2
Essentially, I'd like a count for each of the distinct names when the data is grouped by objects within element.Set.
Ideally, for the example given, I'd like all of:
element.Set.SubListA.AlbertEinstein | 2
element.Set.SubListA.JohnDoe | 1
element.Set.MoreNames.TimMcGraw | 1
element.Set.SublistA.JimmyKimmel | 1
I've tried several aggregate queries but none seems to achieve what I'm trying to do.