want to get following following JSON output - json

I have two tables which are as follows:
quote_glass_types
id | name
1 clear float glass
2 Tinted glass
quote_glass_type_thickness
id | quote_glass_type_id_fk | thickness
1 1 5mm
2 1 8mm
3 2 5mm
4 2 8mm
Now, I would like to join these two tables and get Json as follows:
[
{
id:1,
name: "clear float glass",
thickness:{"5mm","8mm" }
},
{
id:2
name:"tinted glass",
thickness:{"5mm","8mm"}
}
]
Till now I have done like this:
$glasssetting=\DB::table('quote_glass_types')
->join('quote_glass_type_thickness','quote_glass_type_thickness.quote_glass_type_id_fk','=','quote_glass_types.id')
->select('quote_glass_type_thickness.id','name','thickness')
->get();
return $glasssetting;
which gives JSON like:
[
{
"id": 1,
"name": "Clear Float Glasss",
"thickness": "5mm"
},
{
"id": 2,
"name": "Clear Float Glasss",
"thickness": "8mm"
},
{
"id": 3,
"name": "Tinted glass",
"thickness": "5mm"
},
{
"id": 4,
"name": "Tinted glass",
"thickness": "8mm"
}
]
How do I get the required json?

Just use Eloquent for example
return App\QuoteGlassType::with('thickness')->get();
I dont know your Modelname but thats what you are looking for.
Of course make also sure to set the correct Relationships within your Model.

Related

INNER JOIN in jq

Using the input given, I need to join the true "user" value from the tweets array with the id in the users array and display the users array object as part of the tweets array
Input:
{
"tweets": [
{
"tweet": "Hey, i gonna release GPT4 soon",
"user": 1
},
{
"tweet": "We have launched falcon 10 yesterday, it was awesome, one step closer to Mars",
"user": 2
},
{
"tweet": "Databar acquires Statista.com, great news coming out",
"user": 3
},
{
"tweet": "Gpt4 is available",
"user": 1
}
],
"users": [
{ "id": 1, "name": "a" },
{ "id": 2, "name": "b" },
{ "id": 3, "name": "c" }
]
}
Output
[
{
"tweet": "Hey, i gonna release GPT4 soon",
"user": {
"id": 1,
"name": "a"
}
},
{
"tweet": "We have launched falcon 10 yesterday, it was awesome, one step closer to Mars",
"user": {
"id": 2,
"name": "b"
}
},
{
"tweet": "Databar acquires Statista.com, great news coming out",
"user": {
"id": 3,
"name": "c"
}
},
{
"tweet": "Gpt4 is available",
"user": {
"id": 1,
"name": "a"
}
}
]
I tried using an if condition to find the equal values first, but it loops through the entire array, hence I cant get the specific value of the value in the users array that the ID is equal too
Build an INDEX, then use that to map your tweets:
INDEX(.users[]; .id) as $idx | .tweets | map({ tweet, user: $idx[.user|tostring] })
or using JOIN directly:
[JOIN(INDEX(.users[]; .id); .tweets[]; .user|tostring; .[0] + { user: .[1] })]
You could also do it the inefficient way, finding the correct user by iterating:
.users as $users
| .tweets
| map({ tweet, user: (.user as $user | $users[] | select(.id == $user))})
#knittl's solutions using INDEX are fine unless there is a "collision" of ids (e.g. if .id can be both 1 and "1").
To avoid collisions and to allow other types of .id values, you could use
SAFE_INDEX and lookup defined as follows:
def SAFE_INDEX(stream; idx_expr):
reduce stream as $row ({};
($row|idx_expr) as $ix
| .[$ix|type][$ix|tostring] = $row);
def lookup($value):
.[$value|type] as $t
| if ($t|type) == "object" then $t[$value|tostring] else null end;
So a generic solution to the problem would look like this:
SAFE_INDEX(.users[]; .id) as $idx
| .tweets
| map({ tweet, user: (.user as $user | $idx |lookup($user)) })

Change type of input from string to data, MONGO DB

i'm trying to convert the inspection_date field from string to date for every object inside my db.
Every object is built like this one.
"name": "$1 STORE",
"address": "5573 ROSEMEAD BLVD",
"city": "TEMPLE CITY",
"zipcode": "91780",
"state": "California",
"violations": [{
"inspection_date": "2015-09-29",
"description": " points ... violation_status\n62754 1 ... OUT OF COMPLIANCE\n62755 1 ... OUT OF COMPLIANCE\n62756 2 ... OUT OF COMPLIANCE\n\n[3 rows x 5 columns]",
"risk": "Risk 3 (Low)"
}, {
"inspection_date": "2016-08-18",
"description": " points ... violation_status\n338879 2 ... OUT OF COMPLIANCE\n\n[1 rows x 5 columns]",
"risk": "Risk 3 (Low)"
} //could be more than 2 or less then 2 object inside violations array//]}
How can i convert all of the inspection_date field avoiding doing it by myself one by one?
As suggested by #turivishal, you have to have to make use of $map and $dateFromString operators.
db.collection.aggregate([
{
"$addFields": {
"violations": {
"$map": {
"input": "$violations",
"in": {
"$mergeObjects": [
"$$this",
{
"inspection_date": {
"$dateFromString": {
"dateString": "$$this.inspection_date",
"format": "%Y-%m-%d",
"onError": null,
"onNull": null
}
}
}
],
},
}
}
}
},
])
Mongo Playground Sample Execution

Copy value from grandchildren if it exists, use null otherwise

Given the JSON:
{
"id": 1,
"coding": [{
"code": 1234,
"system": "target"
}, {
"code": 5678,
"system": "other"
}]
}
I can select the value of "code" where the "system" is "target", thus:
{id: .id} + {"code": .coding[]? | select(.system=="target").code}
To produce:
{
"id": 1,
"code": 1234
}
But if the object whose "system" value is "target" does not exist in the array, thus:
{
"id": 1,
"coding": [{
"code": 5678,
"system": "other"
}]
}
I want the following result:
{
"id": 1,
"code": null
}
However, my above jq produces an empty object. How can I achieve what I want?
The select built-in yields empty unless at least one of its inputs meets the given criteria, and empty consumes almost anything around itself. Hence the empty result.
Instead, use the first built-in for alternating between the code value from the object where system is target, and null. This also covers some other cases you didn't mention explicitly.
{ id, code: first((.coding[]? | select(.system == "target") .code), null) }
Online demo

Add new fields to nested JSON array in JSONB

I have a nested JSON structure stored in a PostgreSQL table.
Table users:
id | content [JSON]
JSON:
{
"purchases": [
{
"id": 1,
"costs": [
{
"amount": 23
},
{
"amount": 34
}
]
},
{
"id": 2,
"costs": [
{
"amount": 42
}
]
}
]
}
I would like to add a field "jsonClass": "Static" to all the objects within the costs array so I have following in the end:
{
"purchases": [
{
"id": 1,
"costs": [
{
"jsonClass": "Static",
"amount": 23
},
{
"jsonClass": "Static",
"amount": 34
}
]
},
{
"id": 2,
"costs": [
{
"jsonClass": "Static",
"amount": 42
}
]
}
]
}
I couldn't figure out how to add values to such a nested structure. Anyone knows how to achieve such thing? The only way I found was to make it a text and do string replace which is not very performant and I have a lot of such entries.
Unfortunately, due to having to change multiple sub-objects, I don't know of a better way than to deconstruct and then reconstruct the object. It gets pretty hairy.
UPDATE users
SET content=(
SELECT jsonb_agg(purchase)
FROM (
SELECT jsonb_build_object('id', pid, 'purchases', jsonb_agg(cost)) AS purchase
FROM (
SELECT pid, cost || '{"jsonClass":"static"}'::jsonb AS cost
FROM (
SELECT purchase->'id' AS pid, jsonb_array_elements(purchase->'costs') AS cost
FROM jsonb_array_elements(content::jsonb->'purchases') AS purchase
) AS Q
) AS R
GROUP BY pid
) AS S
);
Fiddle
EDIT: Sorry about all the edits, forgot to test for multiple rows. Should be good now. It might be possible to simplify it a bit more, not sure.

How to search nested JSON in MySQL

I am using MySQL 5.7+ with the native JSON data type. Sample data:
[
{
"code": 2,
"stores": [
{
"code": 100,
"quantity": 2
},
{
"code": 200,
"quantity": 3
}
]
},
{
"code": 4,
"stores": [
{
"code": 300,
"quantity": 4
},
{
"code": 400,
"quantity": 5
}
]
}
]
Question: how do I extract an array where code = 4?
The following (working) query has the position of the data I want to extract and the search criterion hardcoded:
SELECT JSON_EXTRACT(data_column, '$[0]')
FROM json_data_table
WHERE data_column->'$[1].code' = 4
I tried using a wildcard (data_column->'$[*].code' = 4) but I get no results in return.
SELECT row FROM
(
SELECT data_column->"[*]" as row
FROM json_data_table
WHERE 4 IN JSON_EXTRACT(data_column, '$[*].code')
)
WHERE row->".code" = 4
... though this would be much easier to work with if this wasn't an unindexed array of objects at the top level. You may want to consider some adjustments to the schema.
Note:
If you have multiple rows in your data, specifying "$[i]" will pick that row, not the aggregate of it. With your dataset, "$[1].code" will always evaluate to the value of code in that single row.
Essentially, you were saying:
$ json collection
[1] second object in the collection.
.code attribute labeled "code".
... since there will only ever be one match for that query, it will always eval to 4...
WHERE 4 = 4
Alternate data structure if possible
Since the entire purpose of "code" is as a key, make it the key.
[
"code2":{
"stores": [
{
"code": 100,
"quantity": 2
},
{
"code": 200,
"quantity": 3
}
]
},
"code4": {
"stores": [
{
"code": 300,
"quantity": 4
},
{
"code": 400,
"quantity": 5
}
]
}
]
Then, all it would require would be:
SELECT datacolumn->"[code4]" as code4
FROM json_data_table
This is what you are looking for.
SELECT data_column->'$[*]' FROM json_data_table where data_column->'$[*].code' like '%4%'.
The selected data will have [] around it when selecting from an array thus data_column->'$[*].code' = 4 is not possible.