Flatten nested powershell object - json

I have a Json-response stored as a powershell object if I convert it back to JSON it looks like this:
[
{
"Guid": "69613454-c846-41c8-b4f2-e29a086c93c0",
"object": [
{
"id": "1",
"value": "Example 1"
},
{
"id": "2",
"value": "Example 2"
},
{
"id": "3",
"value": "Example 3"
}
]
},
{
"Guid": "507610ac-fe09-46bb-ad3d-7948008e5687",
"object": [
{
"id": "1",
"value": "Example 4"
},
{
"id": "2",
"value": "Example 5"
},
{
"id": "3",
"value": "Example 6"
}
]
}
]
And if I list the powershell object ($jsonresponse)
Guid object
---- ------
69613454-c846-41c8-b4f2-e29a086c93c0 {#{id=1; value=Example 1}, #{id=2; value=Example 2}, #{id=3; value=Example 3}}
507610ac-fe09-46bb-ad3d-7948008e5687 {#{id=1; value=Example 4}, #{id=2; value=Example 5}, #{id=3; value=Example 6}}
So I'd like to list only two columns, one containing the Guid and the second only the value that belongs to id 1.
Guid object
---- ------
69613454-c846-41c8-b4f2-e29a086c93c0 Example 1
507610ac-fe09-46bb-ad3d-7948008e5687 Example 4
Tried $jsonresponse | Select-Object -Property Guid -ExpandProperty Object
but get Select-Object: The property cannot be processed because the property "guid" already exists.

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

de structure json nested object

I have the following json which are nested. I am looking for the better approach to read the data. Below is the sample json
[
{
"id": 1,
"name": "some text",
"selections": [
{
"id": 38383,
"items": [
{
"type": "view",
"children": [
{
"nodeId": "groups",
"children": [
{
"nodeId": "groups 1",
"children": [
{
"type": "group level item",
"name": "text1",
"leaf": true,
"info": [
"groups ",
"groups 1",
"groups 2"
]
},
{
"type": "group level item",
"name": "text2",
"leaf": true,
"info": [
"groups ",
"groups 1",
"groups 2"
]
}
]
}
]
}
]
}
]
}
]
},
{
"id": 2,
"name": "some text",
"selections": [
{
"id": 23232,
"items": [
{
"type": "view",
"children": [
{
"nodeId": "Hirearchy",
"children": [
{
"nodeId": "Hirearchy level 1",
"children": [
{
"nodeId": "Hirearchy level 2",
"children": [
{
"type": "charactreistic value",
"name": "some text 1",
"leaf": true,
"info": [
"Hirearchy",
"Hirearchy level 1",
"Hirearchy level 2",
"Hirearchy level 3"
]
},
{
"type": "characterisitic value",
"name": "some text 2",
"leaf": true,
"info": [
"Hirearchy",
"Hirearchy level 1",
"Hirearchy level 2",
"Hirearchy level 3"
]
}
]
}
]
}
]
}
]
}
]
}
]
},
{
"id": 3,
"name": "some text",
"selections": [
{
"id": 2444,
"items": [
{
"type": "view",
"children": [
{
"nodeId": "category",
"children": [
{
"type": "some value",
"name": "some text 1",
"leaf": true,
"info": [
"category",
"category level 1"
]
},
{
"type": "some value",
"name": "some text 2",
"leaf": true,
"info": [
"category",
"category level 1"
]
}
]
}
]
}
]
}
]
},
{
"id": 4,
"name": "some text",
"selections": [
{
"id": 2444,
"items": [
{
"type": "view",
"children": []
}
]
}
]
},
{
"id": 5,
"name": "some text",
"selections": [
{
"id": 2444,
"items": []
}
]
},
{
"id": 6,
"name": "some text",
"selections": []
}
]
for id 1 - there is 3 levels of nesting and the last one has a property which says leaf = true. so in this i need to de structure the object to get the desire out put like
heading - group 2 (from info arrar)
name - ['text1', 'text2'] from the last leaf
for id 2 - there is 4 levels of nesting and the last one has a property which says leaf = true. so in this i need to de structure the object to get the desire out put like
heading - Hierarchy level 3
name - ['some text1', 'some text2']
for id 3 there is 2 levels of nesting and the last one has a property which says leaf = true. so i this
i need to se structure the object to get the desire output like this
heading - Category 1
name - ['some text 3', 'some text4']
for id 4 - there is 1 level of nesting but the array is blank
for id 5 - there is no nesting and the items array is blank
for id 6 - selections array is blank
Question 1. I need to write a generic method to loop thru the json object and find the node where the property 'leaf' is true.
Question 2. This generic method to work even if the nesting levels are 2 or 3 or 4 or it could be more also
Question 3. This generic method should not break the code when the array is empty also.
Requirement. this is required in angular 10 application where i need to destructure the object
Thanks in advance

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]
)|[.[]];

mongodb find() returns entire db, even with parameter

I have the following db:
{
"a": [{
"name": "foo",
"thing": [{
"name": "bar",
"lyrics": ["1", "2", "3"]
}]
}, {
"name": "abc",
"thing": [{
"name": "123",
"list": ["one", "two"]
}]
}]
}
I can't seem to query it correctly. These two queries return the same thing, the entire db:
db.test.find({"a.name":"abc"})
db.test.find({"a.name":"foo"})
How do I find one collection instead of the whole db?
I would expect the first query to return:
{
"name": "abc",
"thing": [{
"name": "123",
"list": ["one", "two"]
}]
}
The two queries return the same document, because both queries match it.
This is one document
[{
"a": [{
"name": "foo",
"thing": [{
"name": "bar",
"lyrics": ["1", "2", "3"]
}]
}, {
"name": "abc",
"thing": [{
"name": "123",
"list": ["one", "two"]
}]
}]
}]
This is two documents
[{
"a": [{
"name": "foo",
"thing": [{
"name": "bar",
"lyrics": ["1", "2", "3"]
}]
}]
},
{
"a": [{
"name": "abc",
"thing": [{
"name": "123",
"list": ["one", "two"]
}]
}]
}]
You can get stats on of a collection like so
db.test.stats()
"count" will tell you how many documents are there.
Edit: To add to this, in your collection "test" a document has 1 field, which is "a" and is of type array that holds objects (documents). It has 2 array elements
First
{
"name": "foo",
"thing": [{
"name": "bar",
"lyrics": ["1", "2", "3"]
}]
}
Second
{
"name": "abc",
"thing": [{
"name": "123",
"list": ["one", "two"]
}]
}
Everything inside curly braces {..}, including the braces themselves, is a one single document, i.e. the whole your database contains only one document that you receive for any matching query. To receive the desired result, you have to re-write your JSON document as an array of documents inside square braces [..].

Get Li3 to return JSON results as an array of objects, not an object of objects

I am trying to utilize the JSON result of a GET request to my Li3 app, but I would like the result to be an array of the returned JSON objects, rather than an object of the JSON objects.
I have the following code in my view file (index.html.php):
print($todos->to('json'));
Which results in each row becoming a JSON object (good), but within an over-arching JSON object.
{
"1": {
"id": "1",
"title": "One",
"done": "0"
},
"2": {
"id": "2",
"title": "Two",
"done": "0"
},
"3": {
"id": "3",
"title": "Three",
"done": "0"
},
"4": {
"id": "4",
"title": "Four",
"done": "0"
}
}
I would like to get:
[
{
"id": "1",
"title": "One",
"done": "0"
},
{
"id": "2",
"title": "Two",
"done": "0"
},
{
"id": "3",
"title": "Three",
"done": "0"
},
{
"id": "4",
"title": "Four",
"done": "0"
}
]
Note: I've found that this was the case (array of objects) in commit "974469cf25db5cbab61f3e1ff172405f4635032e" of the lithium github project, but with anything after that commit, the result is an object of objects.
Try $todos->to('json', ['indexed' => false]), or, refer to the Media class for direct serialization of JSON without the template.
Todos::all(['return' => 'array'))->to('json'); works perfect with RecordSet too