How to project column name and value from JSON in KQL? - json

I have the following 'SetOfSignals' in KQL (using mv-expand):
"SetOfSignals": {
"name": "CompanyName",
"signals": [
{
"name": "AmbientAirTemperature",
"unit": "C",
"dataType": "Float32",
"values": [
"11.5"
]
},
{
"name": "AverageEnergyConsumption",
"unit": "W",
"dataType": "Float32",
"values": [
"780.0"
]
}
}
and now I want to project the signal names with corresponding values.
I want it to look like this:
...
AmbientAirTemperature
AverageEnergyConsumption
...
11.5
780.0
but using something like | extend AmbientAirTemperature = signals.name doesn't works since there are multiple strings within "signals" with the name "name".
Thanks.

datatable(SetOfSignals:dynamic)
[
dynamic
(
{
"name": "CompanyName",
"signals": [
{
"name": "AmbientAirTemperature",
"unit": "C",
"dataType": "Float32",
"values": [
"11.5"
]
},
{
"name": "AverageEnergyConsumption",
"unit": "W",
"dataType": "Float32",
"values": [
"780.0"
]
}
]
}
)
]
| mv-apply signal = SetOfSignals.signals on
(
summarize make_bag(bag_pack(tostring(signal.name), signal.values[0]))
)
| project-away SetOfSignals
| evaluate bag_unpack(bag_)
AmbientAirTemperature
AverageEnergyConsumption
11.5
780.0
Fiddle

Related

JQ - unique count of each value in an array

I'm needing to solve this with JQ. I have a large lists of arrays in my json file and am needing to do some sort | uniq -c types of stuff on them. Specifically I have a relatively nasty looking fruit array that needs to break down what is inside. I'm aware of unique and things like that, and imagine there is likely a simple way to do this, but I've been trying run down assigning things as variables and appending and whatnot, but I can't get the most basic part of counting the unique values per that fruit array, and especially not without breaking the rest of the content (hence the variable ideas). Please tell me I'm overthinking this.
I'd like to turn this;
[
{
"uid": "123abc",
"tID": [
"T19"
],
"fruit": [
"Kiwi",
"Apple",
"",
"",
"",
"Kiwi",
"",
"Kiwi",
"",
"",
"Mango",
"Kiwi"
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"fruit": [
"",
"Orange"
]
}
]
Into this;
[
{
"uid": "123abc",
"tID": [
"T19"
],
"metadata": [
{
"name": "fruit",
"value": "Kiwi - 3"
},
{
"name": "fruit",
"value": "Mango - 1"
},
{
"name": "fruit",
"value": "Apple - 1"
}
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"metadata": [
{
"name": "fruit",
"value": "Orange - 1"
}
]
}
]
Using group_by and length would be one way:
jq '
map(with_entries(select(.key == "fruit") |= (
.value |= (group_by(.) | map(
{name: "fruit", value: "\(.[0] | select(. != "")) - \(length)"}
))
| .key = "metadata"
)))
'
[
{
"uid": "123abc",
"tID": [
"T19"
],
"metadata": [
{
"name": "fruit",
"value": "Apple - 1"
},
{
"name": "fruit",
"value": "Kiwi - 4"
},
{
"name": "fruit",
"value": "Mango - 1"
}
]
},
{
"uid": "456xyz",
"tID": [
"T15"
],
"metadata": [
{
"name": "fruit",
"value": "Orange - 1"
}
]
}
]
Demo

jq sort by value of key

Given the following JSON (oversimplified for the sake of the example), I need to order the keys by their value. In this case, the order should be id > name > type.
{
"link": [{
"attributes": [{
"value": "ConfigurationElement",
"name": "type"
}, {
"value": "NAME1",
"name": "name"
}, {
"value": "0026a8b4-ced6-410e-9213-e3fcb28b3aab",
"name": "id"
}
],
"href": "href1",
"rel": "down"
}, {
"attributes": [{
"value": "0026a8b4-ced6-410e-9213-k23g15h2u1l5",
"name": "id"
}, {
"value": "ConfigurationElement",
"name": "type"
}, {
"value": "NAME2",
"name": "name"
}
],
"href": "href2",
"rel": "down"
}
],
"total": 2
}
EXPECTED RESULT:
{
"link": [{
"attributes": [{
"value": "0026a8b4-ced6-410e-9213-e3fcb28b3aab",
"name": "id"
}, {
"value": "NAME1",
"name": "name"
}, {
"value": "ConfigurationElement",
"name": "type"
}
],
"href": "href1",
"rel": "down"
}, {
"attributes": [{
"value": "0026a8b4-ced6-410e-9213-k23g15h2u1l5",
"name": "id"
}, {
"value": "NAME2",
"name": "name"
}, {
"value": "ConfigurationElement",
"name": "type"
}
],
"href": "href2",
"rel": "down"
}
],
"total": 2
}
I would be very grateful if anyone could help me out. I tried jq with -S and -s with sort_by(), but this example is way too complex for me to figure it out with my current experience with jq. Thank you a lot!
You can do:
jq '.link[].attributes|=sort_by(.name)'
The |= takes all the paths matched by .link[].attributes, i.e. each "attributes" array, and applies the filter sort_by(.name) to each of them, leaving everything else unchanged.

JSONpath to get a value by filter on another value

I have below JSON and i require to validate the status based on given id in my automation script. For that JSON path require
[
[
{
"id": 9905130204,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
},
{
"id": 9905130203,
"name": "Jeffs Doggie11/6/2019 2:44:53 PM",
"photoUrls": [
"string"
],
"tags": [],
"status": "available"
},
{
"id": 9905130217,
"name": "Goot Doggie",
"photoUrls": [
"https://media.karousell.com/media/photos/products/2017/09/14/doggi_door_stopper_1505372529_5cdd1eba0"
],
"tags": [],
"status": "available"
}
]
]
I want to extract "status": "available" based on "id": 9905130217. No clue how to do that, please help.
You can use the following jsonpath expression to find the status where id = n:
$.[?(#.id == 'n')].status
So, for your specific case:
$.[?(#.id == '9905130217')].status
Note, that this assumes id is unique.

Using jq to convert object to key with values

I have been playing around with jq to format a json file but I am having some issues trying to solve a particular transformation. Given a test.json file in this format:
[
{
"name": "A", // This would be the first key
"number": 1,
"type": "apple",
"city": "NYC" // This would be the second key
},
{
"name": "A",
"number": "5",
"type": "apple",
"city": "LA"
},
{
"name": "A",
"number": 2,
"type": "apple",
"city": "NYC"
},
{
"name": "B",
"number": 3,
"type": "apple",
"city": "NYC"
}
]
I was wondering, how can I format it this way using jq?
[
{
"key": "A",
"values": [
{
"key": "NYC",
"values": [
{
"number": 1,
"type": "a"
},
{
"number": 2,
"type": "b"
}
]
},
{
"key": "LA",
"values": [
{
"number": 5,
"type": "b"
}
]
}
]
},
{
"key": "B",
"values": [
{
"key": "NYC",
"values": [
{
"number": 3,
"type": "apple"
}
]
}
]
}
]
I have followed this thread Using jq, convert array of name/value pairs to object with named keys and tried to group the json using this expression
jq '. | group_by(.name) | group_by(.city) ' ./test.json
but I have not been able to add the keys in the output.
You'll want to group the items at the different levels and building out your result objects as you want.
group_by(.name) | map({
key: .[0].name,
values: (group_by(.city) | map({
key: .[0].city,
values: map({number,type})
}))
})
Just keep in mind that group_by/1 yields groups in a sorted order. You'll probably want an implementation that preserves that order.
def group_by_unsorted(key_selector):
reduce .[] as $i ({};
.["\($i|key_selector)"] += [$i]
)|[.[]];

JSON Parse key to a table column SQL Server 2016

We are receiving this JSON document and importing into SQL Server 2016 using Kingswaysoft JSON Source component
{
"Program": "USRMI",
"Transaction": "GetUserInfo",
"Metadata": {
"Field": [
{
"#name": "USERID",
"#type": "A",
"#length": 10,
"#description": "User"
},
{
"#name": "COMPNO",
"#type": "N",
"#length": 3,
"#description": "Company"
},
]
},
"MIRecord": [
{
"NameValue": [
{
"Name": "USERID",
"Value": "JOEBLO88"
},
{
"Name": "COMPNO",
"Value": "999"
},
],
"RowIndex": 0
}
{
"NameValue": [
{
"Name": "USERID",
"Value": "JOEBLO55"
},
{
"Name": "COMPNO",
"Value": "998"
},
],
"RowIndex": 1
}
]
}
and have a column in a table as follows:
{"Name": "USERID","Value": "JOBLO88"}
{"Name": "COMPNO","Value": "988"}
{"Name": "USERID","Value": "JOBLO55"}
{"Name": "COMPNO","Value": "955"}
I'm struggling to find any resource on syntax that can be used to convert this into a column structured table as per below
USERID COMPNO
====== ======
JOBLO88 988
JOBLO55 955