I have the following JSON object r2,
[
{
"reserva_id":"200",
"estancias":[
{
"reserva_estancia":"266",
"huespedes":[
{
"reserva_huesped":"272",
"reserva_estancia":"266",
"numero_huesped":"1",
"huesped":"123",
"huesped_nombre":"dos dos, dos",
"rfid":null
},
{
"reserva_huesped":"276",
"reserva_estancia":"266",
"numero_huesped":"2",
"huesped":"183",
"huesped_nombre":"MUESTRA MUESTRA, CARMEN",
"rfid":null
}
]
}
]
},
{
"reserva_id":"201",
"estancias":[
{
"huespedes":[
{
"reserva_huesped":"273",
"reserva_estancia":"267",
"numero_huesped":"1",
"huesped":"148",
"huesped_nombre":"MUESTRA MUESTRA, CARMEN",
"rfid":null
},
{
"reserva_huesped":"277",
"reserva_estancia":"267",
"numero_huesped":"2",
"huesped":"187",
"huesped_nombre":"TEST TEST, TESTCIVITFUN",
"rfid":null
}
]
}
]
}
]
I am trying to get the first huesped for each reservation, and for that I am using the following script, to create a list called profiles and store profileId's:
def profiles = jsonpath(r2,'$..[:].estancias[:].huespedes[0].huesped')
The output should be the following:
[
"123",
"148"
]
However, when I print profiles.text I get all the content of the estancias object, instead of just the huesped number.
When using Jayway's JSONPath like this I get the desired oputput:
$..[*].estancias[*].huespedes[0].huesped
You can try the path expression with your JSON here online.
Related
I am in no way an expert with groovy so please don't hold that against me.
I have JSON that looks like this:
{
"metrics": [
{
"name": "metric_a",
"help": "This tracks your A stuff.",
"type": "GAUGE",
"labels": [
"pool"
],
"unit": "",
"aggregates": [],
"meta": [
{
"category": "CAT A",
"deployment": "environment-a"
}
],
"additional_notes": "Some stuff (potentially)"
},
...
]
...
}
I'm using it as a source for automated documentation of all the metrics. So, I'm iterating through it in various ways to get the information I need. So far so good, I'm most of the way there. The problem is this all needs to be organized per the deployment environment. Meaning, multiple metrics will share the same value for deployment.
My thought was I could create a map with deployment as the key and the metric name for any metric that has a matching deployment as the value. Once I have that map, it should be easy for me to organize things the way they should be. I can't figure out how to do that. The result is all the metric names are added which is expected since I'm not doing anything to filter them out. I was thinking that groupBy would make sense here but I can't figure out how to use it effectively and frankly I'm not sure it will solve my problem by itself. Here is my code so far:
parentChild = [:]
children = []
metrics.each { metric ->
def metricName = metric.name
def depName = metric.meta.findResult{ it.deployment }
children.add(metricName)
parentChild.put(depName, children)
}
What is the best way to create a new map where the values for each key are based off a specific condition?
EDIT: The desired result would be each key in the resulting map would be a unique deployment value from all the metrics (as a string). Each value would be name of each metric that contains that deployment (as an array).
[environment-a:
[metric_a,metric_b,metric_c,...],
environment-b:
[metric_d,metric_e,metric_f,...]
...]
I would use a combo of withDefault() to pre-fill each map-entry value with a fresh TreeSet-instance (sorted no-duplicates set) and standard inject().
I reduced your sample data to the bare minimum and added some new nodes:
import groovy.json.*
String input = '''\
{
"metrics": [
{
"name": "metric_a",
"meta": [
{
"deployment": "environment-a"
}
]
},
{
"name": "metric_b",
"meta": [
{
"deployment": "environment-a"
}
]
},
{
"name": "metric_c",
"meta": [
{
"deployment": "environment-a"
},
{
"deployment": "environment-b"
}
]
},
{
"name": "metric_d",
"meta": [
{
"deployment": "environment-b"
}
]
}
]
}'''
def json = new JsonSlurper().parseText input
def groupedByDeployment = json.metrics.inject( [:].withDefault{ new TreeSet() } ){ res, metric ->
metric.meta.each{ res[ it.deployment ] << metric.name }
res
}
assert groupedByDeployment.toString() == '[environment-a:[metric_a, metric_b, metric_c], environment-b:[metric_c, metric_d]]'
If your metrics.meta array is supposed to have a single value, you can simplify the code by replacing the line:
metric.meta.each{ res[ it.deployment ] << metric.name }
with
res[ metric.meta.first().deployment ] << metric.name
I have a json data file from which I need to fetch only the id attribute value into a separate list variable. I tried for loop but not able to get the required data using terraform. Can someone tell how to fetch the id part ? your help is much appreacited.
code:
locals {
data = jsondecode(file("./data.json"))[*]
sections = [ for item in local.data : item ]
}
output "ids" {
value = [for a in local.sections[0]: a]
}
json file:
{
"c":[
{
"id":"6",
"key":"c",
"name":"s01"
}
],
"l":{
"id":"7",
"key":"l",
"name":"s02"
},
"m":{
"id":"8",
"key":"mp",
"name":"s03"
},
"n":{
"id":"5",
"key":"cn",
"name":"s04"
},
"od":"odk",
"s":{
"id":"9",
"key":"cs",
"name":"s05"
},
"ss":{
"id":"1",
"key":"ss",
"name":"s06"
},
"in":{
"id":"65",
"key":"cn",
"name":"s07"
},
"b":{
"id":"2",
"key":"cb",
"name":"s08"
}
}
Not sure if "od":"odk", is mistake or not, but you can do the following:
locals {
data = jsondecode(file("./data.json"))
}
output "ids" {
value = [for v in values(local.data): v.id if can(v.id)]
}
I have a dictionary below. I want to convert the string to list in Body section ("Body":"{"abc": "test"}"). My requirement is that I will post the whole dictionary and it will convert that into valid json object.
details = {
"bb":[
{
"bb_name":[
"baca"
]
}
],
"spd":[
{
"id_":1,
"schema":{
"method":"GET",
"url":"http://api.myapi.com/12232",
"Headers":[
],
"Parameters":[
],
"Body":"{\"abc\": \"test\"}"
}
}
]
}
I am planning to retrieve the child elements all the parent, How can i retrieve it, being inside the array of array objects.
SELECT sd.*
FROM test AS t
UNNEST stateDetails AS sd;
{
"type":"countries",
"docName":"CountryData",
"countryDetails":[
{
"name":"US",
"code":"+1",
"stateInfo":[
{
"name":"Florida",
"id":"1212"
},
{
"name":"NewYork",
"id":"1214"
}
]
},
{
"name":"France",
"code":"+33",
"stateInfo":[
{
"name":"Grand Est",
"id":"5212"
},
{
"name":"Brittany",
"id":"5214"
}
]
}
]
}
I am expecting the following output to bring out the state details of all the countries with their respective country Name
[
{
"countryName":"US",
"name":"Florida",
"id":"1212"
},
{
"countryName":"US",
"name":"NewYork",
"id":"1214"
},
{
"countryName":"France",
"name":"Grand Est",
"id":"5212"
},
{
"countryName":"France",
"name":"Brittany",
"id":"5214"
}
]
Use double UNNEST and project what you need
SELECT cd.name AS countryName, sd.name, sd.id
FROM test AS t
UNNEST t.countryDetails AS cd
UNNEST cd.stateInfo AS sd
WHERE t.type = "countries";
{
TypeList" : [
{
"TypeName" : "Carrier"
},
{
"TypeName" : "Not a Channel Member"
},
{
"TypeName" : "Service Provider"
}
]
}
Question :
db.supplies.find("text", {search:"\"chann\" \"mem\""})
For above query I want display :
{
TypeName" : "Not a Channel Member"
}
But I am unable to get my result.
What are changes I have to do in query .
Please help me.
The below query will return your desired result.
db.supplies.aggregate([
{$unwind:"$TypeList"},
{$match:{"TypeList.TypeName":{$regex:/.*chann.*mem.*/,$options:"i"}}},
{$project:{_id:0, TypeName:"$TypeList.TypeName"}}
])
If you can accept to get an output like this:
{
"TypeList" : [
{
"TypeName" : "Not a Channel Member"
}
]
}
then you can get around using the aggregation framework which generally helps performance by running the following query:
db.supplies.find(
{
"TypeList.TypeName": /chann.*mem/i
},
{ // project the list in the following way
"_id": 0, // do not include the "_id" field in the output
"TypeList": { // only include the items from the TypeList array...
$elemMatch: { //... where
"TypeName": /chann.*mem/i // the "TypeName" field matches the regular expression
}
}
})
Also see this link: Retrieve only the queried element in an object array in MongoDB collection