How to get the length of a JSON array using JSONPath? - json

If I have JSON document like this
[
{
"number" : "650-462-9154",
"type" : "main"
},
{
"number" : "650-462-1252",
"type" : "fax"
}
]
What JSONPath can I use to get the array length (which is 2), without hardcoding any property values?
Using the tool I have, here is some examples they gave, which doesn't help me figure out what value I need.
[
{
"type": "add",
"id": "tt0484562",
"version": 1,
"lang": "en",
"fields": {
"title": "The Seeker: The Dark Is Rising",
"director": "Cunningham, David L.",
"genre": ["Adventure","Drama","Fantasy","Thriller"],
"actor": ["McShane, Ian","Eccleston, Christopher","Conroy, Frances",
"Crewson, Wendy","Ludwig, Alexander","Cosmo, James",
"Warner, Amelia","Hickey, John Benjamin","Piddock, Jim",
"Lockhart, Emma"]
}
},
{
"type": "delete",
"id": "tt0484575",
"link_ref": null,
"version": 2
}
]
$.[0].genre ---> 0
$.[0].fields.genre ---> 1
$.[0].fields.genre[*] ---> 4
$.[*].type ---> 2
$.[1].link_ref ---> 1

You can get the length of the array from the first example by using the .length() function like this :
$.length
That should return something like this:
[
2
]
As for the second example, you can access any array keys using regular dot notation ($.node1.node2.node3) and call the length() function on the node key you wish to get the length of. For example, if you wanted to get the number of values in the actor array you could do something like:
$..actor.length
Which will return something like this:
[
10
]
Tested on https://codebeautify.org/jsonpath-tester and http://jsonpath.com/ .
You can find more functions in the jsonpath github repo.

Related

Retrieve specific value from a JSON blob in MS SQL Server, using a property value?

In my DB I have a column storing JSON. The JSON looks like this:
{
"views": [
{
"id": "1",
"sections": [
{
"id": "1",
"isToggleActive": false,
"components": [
{
"id": "1",
"values": [
"02/24/2021"
]
},
{
"id": "2",
"values": []
},
{
"id": "3",
"values": [
"5393",
"02/26/2021 - Weekly"
]
},
{
"id": "5",
"values": [
""
]
}
]
}
]
}
]
}
I want to create a migration script that will extract a value from this JSON and store them in its own column.
In the JSON above, in that components array, I want to extract the second value from the component with an ID of "3" (among other things, but this is a good example). So, I want to extract the value "02/26/2021 - Weekly" to store in its own column.
I was looking at the JSON_VALUE docs, but I only see examples for specifing indexes for the json properties. I can't figure out what kind of json path I'd need. Is this even possible to do with JSON_VALUE?
EDIT: To clarify, the views and sections components can have static array indexes, so I can use views[0].sections[0] for them. Currently, this is all I have with my SQL query:
SELECT
*
FROM OPENJSON(#jsonInfo, '$.views[0].sections[0]')
You need to use OPENJSON to break out the inner array, then filter it with a WHERE and finally select the correct value with JSON_VALUE
SELECT
JSON_VALUE(components.value, '$.values[1]')
FROM OPENJSON (#jsonInfo, '$.views[0].sections[0].components') components
WHERE JSON_VALUE(components.value, '$.id') = '3'

Using Power Query to extract data from nested arrays in JSON

I'm relatively new to Power Query, but I'm pulling in this basic structure of JSON from a web api
{
"report": "Cost History",
"dimensions": [
{
"time": [
{
"name": "2019-11",
"label": "2019-11",
…
},
{
"name": "2019-12",
"label": "2019-12",
…
},
{
"name": "2020-01",
"label": "2020-01",
…
},
…
]
},
{
"Category": [
{
"name": "category1",
"label": "Category 1",
…
},
{
"name": "category2",
"label": "Category 2",
…
},
…
]
}
],
"data": [
[
[
40419.6393798211
],
[
191.44
],
…
],
[
[
2299.652439184997
],
[
0.0
],
…
]
]
}
I actually have 112 categories and 13 "times". I figured out how to do multiple queries to turn the times into column headers and the categories into row labels (I think). But the data section is alluding me. Because each item is a list within a list I'm not sure how to expand it all out. Each object in the date array will have 112 numbers and there will be 13 objects. If that all makes sense.
So ultimately I want to make it look like
2019-11 2019-20 2020-01 ...
Category 1 40419 2299
Category 2 191 0
...
First time asking a question on here, so hopefully this all makes sense and is clear. Thanks in advance for any help!
i am also researching this exact thing and looking for a solution. In PQ, it displays nested arrays as a list and there is a function to extract values choosing a separating characterenter image description here
So this becomes, this
enter image description here
= Table.TransformColumns(#"Filtered Rows", {"aligned_to_ids", each Text.Combine(List.Transform(_, Text.From), ","), type text})
However the problem i'm trying to solve is when the nested json has multiple values like this: enter image description here
And when these LIST are extracted then an error message is caused, = Table.TransformColumns(#"Extracted Values1", {"collaborators", each Text.Combine(List.Transform(_, Text.From), ","), type text})
Expression.Error: We cannot convert a value of type Record to type Text.
Details:
Value=
id=15890
goal_id=323
role_id=15
Type=[Type]
It seems the multiple values are not handled and PQ does not recognise the underlying structure to enable the columns to be expanded.

Get value from exact JSONpath level

I want to extract values from an JSON document with using the path operators.
For example I get all the product IDs included in the file via $..product_id.
But for getting the "id" when I use $..id I get an output for each id element, no matter on which level of the JSON the variable is.
For example in my output I get an row for the id "12345678" as well as for "11223344" which should not be because it is a subset of the first ID.
{
"next_offset": 20,
"records": [
{
"id": "12345678",
"date": "2020-02-14",
"product_id": "asdf1234",
"product_name": "Product_test^_1",
"template_link": {
"name": "aassddff",
"id": "11223344",
"_acl": {
"fields": [],
"_hash": "345thvz356b56v456b"
}
},
....
}
]
}
How can I set the path operator to only access the "id" fields of one specific level?
For the JSON shown in your question, use $.records.*.id.

How to use jq to reconstruct complete contents of json file, operating only on part of interest?

All the examples I've seen so far "reduce" the output (filter out) some part. I understand how to operate on the part of the input I want to, but I haven't figured out how to output the rest of the content "untouched".
The particular example would be an input file with several high level entries "array1", "field1", "array2", "array3" say. Each array contents is different. The specific processing I want to do is to sort "array1" entries by a "name" field which is doable by:
jq '.array1 | sort_by(.name)' test.json
but I also want this output as "array1" as well as all the other data to be preserved.
Example input:
{
"field1": "value1",
"array1":
[
{ "name": "B", "otherdata": "Bstuff" },
{ "name": "A", "otherdata": "Astuff" }
],
"array2" :
[
array2 stuff
],
"array3" :
[
array3 stuff
]
}
Expected output:
{
"field1": "value1",
"array1":
[
{ "name": "A", "otherdata": "Astuff" },
{ "name": "B", "otherdata": "Bstuff" }
],
"array2" :
[
array2 stuff
],
"array3" :
[
array3 stuff
]
}
I've tried using map but I can't seem to get the syntax correct to be able to handle any type of input other than the array I want to be sorted by name.
Whenever you use the assignment operators (=, |=, +=, etc.), the context of the expression is kept unchanged. So as long as your top-level filter(s) are assignments, in the end, you'll get the rest of the data (with your changes applied).
In this case, you're just sorting the array1 array so you could just update the array.
.array1 |= sort_by(.name)

Jqgrid. How to handle server response before in will be passed to grid

I have a common structure of JSON data that come back from server, it contains some additional info about errors etc. How can I handle this data(check error info) and then pass only required data to grid.
This is JSON data structure:
{
"errorinfo": "foo",
"errormsg": "foo",
"errorCode": "foo"
"**jqgridData**": [
{
"total": "xxx",
"page": "yyy",
"records": "zzz",
"rows" : [
{"id" :"1", "cell" :["cell11", "cell12", "cell13"]},
{"id" :"2", "cell":["cell21", "cell22", "cell23"]},
...
]
}
]
}
So I wand to process this JSON data and pass to grid only "jqgridData"
Thanks for help.
First of all the JSON data has one small error. The string
{ "errorinfo": "foo", "errormsg": "foo", "errorCode": "foo" "jqgridData": [ {
must be changed to
{ "errorinfo": "foo", "errormsg": "foo", "errorCode": "foo", "jqgridData": [ {
(comma between "errorCode": "foo" and "jqgridData" must be inserted). I hope the problem come during posting of the data in the question text only.
To your main question. The jsonReader allows you to read you practically any data. You data should be read with the following jsonReader:
jsonReader: {
root: "jqgridData.0.rows",
page: "jqgridData.0.page",
total: "jqgridData.0.total",
records: "jqgridData.0.records"
}
(where '0' element is needed as the index because of jqgridData is additionally an array).