I have the following JSON:
{
"query": "rest ec",
"elected_facts_mapping": {
"AWS": {
"ECS": {
"attachments": [
"restart_ecs"
],
"text": [
"Great!"
]
}
}
},
"top_facts_mapping": {
"AWS": {
"ECS": {
"attachments": [
"restart_ecs"
],
"text": [
"Great!"
]
},
"EC2": {
"attachments": [
"create_ec2"
],
"text": [
"Awesome"
]
}
},
"GitHub": {
"Pull": {
"attachments": [
"pull_req"
],
"text": [
"Be right on it"
]
}
},
"testtttt": {
"test": {
"attachments": [
"hello_world"
],
"text": [
"Be right on it"
]
}
},
"fgjgh": {
"fnfgj": {
"attachments": [
"hello_world"
],
"text": [
"Be right on it"
]
}
},
"tessttertre": {
"gfdgfdgfd": {
"attachments": [
"hello_world"
],
"text": [
"Great!"
]
}
}
},
"elected_facts_with_prefix_text": null
}
And I want to access to top_facts_mapping's
first key AWS
and it’s first key ECS
I am trying to do this (in my DSL):
'.span | fromjson'
'.span_data.top_facts_mapping | keys[0]'
'.span_data.top_facts_mapping[${top_facts_prepare_top_fact_topic}] | keys[0]'
'.top_facts_prepare_top_fact_topic_subtopic[${top_facts_prepare_top_fact_topic}][${top_facts_prepare_top_fact_topic_subtopic}]'
3
Answers
You could use the
keys_unsorted
builtin, since the underlying object is a dictionary and not a listThe above filter could be re-written with a simple function
Or with some jq trick-play, assumes the path provided
top_facts_mapping
is guaranteed to existSince the
paths
built-in constructs the root to leaf paths as arrays, we all paths containing the second to last field (denoted by.[-3]
) as"top_facts_mapping"
which returns paths inside itFrom which
first
selects the first entity in the list i.e. below listUse
getpath/1
to obtain the JSON value at the obtained path.If there is a risk of the key
top_facts_mapping
not being present in the JSON,getpath/1
could return an error as written above. Fix it by adding a proper checkYou could use
to_entries
to turn the object into an array of key-value pairs, then select the first value using[0].value
Demo
If at one level the object may be empty, you can prepend each
to_entries
withtry
(optionally followed by acatch
clause)Here’s a stream-based approach which disassembles the input using the
--stream
option, filters for the "top_facts_mapping" key on top level.[0][0]
, truncates the stream to descend 3 levels, re-assembles the stream usingfromstream
, and outputs thefirst
match: