Reputation: 577
My JSON file has the following structure
[
{
"Header": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "TOMCAT",
"entityId": "SERVICE-728B1FF49D132C89",
"serviceType": "WebRequest",
"webServerName": "www.example.com:80"
},
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-42A0FB8666B36EB4",
"serviceType": "Process"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
I need to apply several filters and leave in the .Body[]
array objects according to different criteria:
.Body[]
array which do not have .webServerName
key present - this condition should leave only the object #2 inside the .Body[]
array.Body[]
array where .webServerName
value is www.example.com:443
- that should leave objects # 0,3..webServerName
key present, so negating the condition #1 - this should leave all object except #2.For #1 the filter below does the job
[.[].Header as $x | (.[].Body[] | select( (.webServerName == null ))) as $y | {Tenant: $x, Body: [$y]} ]
It gives the following output:
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-42A0FB8666B36EB4",
"serviceType": "Process"
}
]
}
]
But when I tried to modify the filter for the condition #2
[.[].Header as $x | (.[].Body[] | select( (.webServerName == "www.example.com:443" ))) as $y | {Tenant: $x, Body: [$y]} ]
This gave me the following output - two entries instead of having one.
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
},
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
While the expected output should look like for case #2:
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
And the following for case #3:
[
{
"Header": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "TOMCAT",
"entityId": "SERVICE-728B1FF49D132C89",
"serviceType": "WebRequest",
"webServerName": "www.example.com:80"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
I am trying to figure out where I made an error - in the selection condition or in the forming of the new object at the end.
Upvotes: 2
Views: 6399
Reputation: 85530
Judging from your requirements, it seems you need an expression to select objects in the .Body[]
array where .webServerName
key is www.example.com:443
or the key basically exists
.[].Body |= map(select(.webServerName == "www.example.com:443" or has("webServerName") ))
Both your attempts though valid are really convoluted. The standard pattern to selectively filter out objects inside the array is to use the |=
operator with the right select
expression.
The | {Tenant: $x, Body: [$y]}
is wrong, because it is applied to each of the 2 objects you filtered in the previous expression. So each of the result has a Tenant
field created. Since you have no change in key names (same key Tenant
), there is really no purpose to re-create new objects with {..}
.
Upvotes: 1