Select object based on value of variable in json array using jq - jq

I have the following json file:
{
"HostedZones": [
{
"Id": "Z3JX6LQV6IJO3E",
"Name": "sandbox.mydomain.com."
},
{
"Id": "Z13M9NFG2E4J5N",
"Name": "internal.mydomain.com."
}
]
}
I am using jq and want to get the "Id" value of the object where 'Name' is 'internal.mydomain.com.'.

Use select() filter on the name and get the id value with the following filter
jq '.HostedZones[] | select (.Name=="internal.mydomain.com.").Id'

Related

Use jq to extract a subset of a nested object's fields?

I have a 26MB JSON file containing UN/LOCODE data that I want to restructure and remove some data from so that it takes less space in my app's binary package.
The JSON contains an array of objects like this:
{
"Change": null,
"Coordinates": "4234N 00135E",
"Country": "AD",
"Date": "0307",
"Function": "--3-----",
"IATA": null,
"Location": "CAN",
"Name": "Canillo",
"NameWoDiacritics": "Canillo",
"Remarks": null,
"Status": "RL",
"Subdivision": null
}
The desired structure is an object rather than an array, keyed on the concatenation of the Country and Location fields, but the only nested fields that I am interested in are "Name" and "Coordinates".
I have been able to accomplish the first step with:
jq 'INDEX("\(.Country)-\(.Location)")'
giving me:
{
"AD-CAN": {
"Change": null,
"Coordinates": "4234N 00135E",
"Country": "AD",
"Date": "0307",
"Function": "--3-----",
"IATA": null,
"Location": "CAN",
"Name": "Canillo",
"NameWoDiacritics": "Canillo",
"Remarks": null,
"Status": "RL",
"Subdivision": null
},
...
}
but I cannot figure out how to get only the desired keys from the nested objects inside the new top-level object.
If this can't be done with jq I'll have to resort to a custom script to do it.
Just reshape the objects using map_values:
jq 'INDEX("\(.Country)-\(.Location)") | map_values({Name, Coordinates})'
Or do it all in one go using reduce:
jq 'reduce .[] as $i ({}; ."\($i.Country)-\($i.Location)" = ($i|{Name, Coordinates}))'
You can use map_values, which applies to filter to every property's value in the object:
INDEX("\(.Country)-\(.Location)") | map_values({Name, Coordinates})
Output:
{
"AD-CAN": {
"Name": "Canillo",
"Coordinates": "4234N 00135E"
}
}

Query an array that contain string with terms

I want filter result from Elasticsearch where array of strings contain one of specific string value:
This is current json result, no filtered :
{
"id": 1,
"title": "Title",
"tags": [
"tag filter"
],
},
{
"id": 2,
"title": "Title",
"tags": [
"different tag filter"
],
},
Objectif : obtain only result where tags contain simple "tag filter"
What i made:
$termsQuery = new Terms('POITypes');
$termsQuery->setTerms($terms); // $terms => array("tag filter")
$boolQuery->addMust($termsQuery);
What dd report:
SearchController.php on line 90:
Elastica\Query\BoolQuery {#892
#_params: array:1 [
"must" => array:1 [
0 => Elastica\Query\Terms {#893
#_params: array:1 [
"tags" => array:1 [
0 => "tag filter"
]
]
#_rawParams: []
-field: "tags"
}
]
]
#_rawParams: []
}
When i add this must filter with this terms requirement, there are 0 result obtain. I found no solution since 2 days for this simple query... what's wrong with my code ?
Expecting only result where tags array includes one of my terms values.
Pass field name as tags.keyword.
Tags field is of type "text" so your query is trying to match "tag filter"against individual tokens["tag","filter"], you need to match it against full value.
If index was auto created , it will have keyword subfield by default, otherwise you will need to create it.

JSON path evaluation inside JSON path expression

I've got this very simple json :
{
"authors": [
{
"id": 1,
"name": "Douglas Adams"
},
{
"id": 2,
"name": "John Doe"
}
],
"books": [
{
"name": "The Hitchhiker's Guide to the Galaxy",
"author_id": 1
}
]
}
I would like to request the name of the author of "The Hitchhiker's Guide to the Galaxy".
I've tried this JSON path but it doesn't work:
$.authors[?(#.id == $.books[?(#.name == "The Hitchhiker's Guide to the Galaxy")].author_id)].name
All online tools I tried indicate a syntax error which seems due to the presence of a JSON path inside my filter.
Could anyone please help me figure out what's wrong and what is the right syntax?
Thanks!
When you running this filter
$.books[?(#.name == "The Hitchhiker's Guide to the Galaxy")].author_id
it returns an array instead of a value:
[
1
]
Syntax error occurs when you pass an array to compare with the value of id:
$.authors[?(#.id == {the array value}].author_id)].name
However, you may not be able to extract the value using JSONPath, depends on the language you are using. See Getting a single value from a JSON object using JSONPath

Can't get the desired properties via JsonPath evaluate method

I have a json schema that marks special properties in need of processing and I want to query those via JsonPath.Evaluate.
Here's a part of the schema to illustrate the issue
{
"type": "object",
"properties": {
"period": {
"description": "The period in which the rule applies",
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
}
},
"required": [
"start"
],
"x-updateIndicatorProperties": [
"start"
]
},
"productType": {
"type": "string"
},
"x-updateIndicatorProperties": [
"productType"
]
}
}
I want to get the the JsonPath of the "x-updateIndicatorProperties" properties, so that I can then query the actual properties to process.
For this example, the expected result would be
[
"$['properties']['x-updateIndicatorProperties']",
"$['properties']['period']['x-updateIndicatorProperties']"
]
I've been trying for a while to get a JsonPath expression that would query these properties.
Currently I'm just iterating all properties and filter them manually :
"$..*"
I've also tried using :
$..['x-updateIndicatorProperties']
This works. But it returns a lot of duplicates. For the example above, I get 5 results instead of the expected 2. Can be demonstrated here : https://json-everything.net/json-path
Assuming I can't influence the schema itself, only the code that traverses it,
can anybody help with an expression to get the expected results or any other way to achieve the same outcome?
The stack is JsonPath 0.2.0, .net 6 and system.text.json.
This was a bug in the library when parsing paths that use a recursive descent (..) into a quoted-property-name selector (['foo']). So it would happen for any path in the form $..['foo'].
I've fixed the issue and released version 0.2.1.

How to filter based on value in json using JQ

{ "amazon": {
"items": [
{
"name": "harry potter",
"state": "sold"
},
{
"name": "adidas shoes",
"state": "in inventory"
},
{
"name": "watch",
"state": "returned"
},
]
}
}
I want to write jq json parsing tool to modify "name:harry potter" from state "sold" to "returned"
I want to modify this in a shell script ( .sh ) file.
Assuming the input is valid JSON, the following filter will perform the edit conditionally as specified:
.amazon.items
|= map(if .name == "harry potter" and .state == "sold"
then .state = "returned" else . end)
Or rather, invoking jq with this filter will emit the updated JSON.
You might want to use sponge to overwrite the original file once you're sure that's really what you want to do.
Another jq filter using select function:
jq '.amazon.items |= map(select(.name=="harry potter").state="returned")' file

Resources