Select sql query to group by nested json - sql

The data I am getting from select query is something like this
[{
id: 'CB2FD8B7-7E6D-4BF3-8E73-70D41FFBE456',
products: '[{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6B7"}]',
falconpay_api_response: null,
dhl_updated_by: null
}, ... ]
What I am doing is fetching orders and then parsing products attribute and extracting product_id and counting the number of time the product_id occured in the number of different json objects.
This would be very time consuming if number of rows to fetch are in thousands and then extracting ids and counting its occurrences.
Is there any effective way to use GROUP by and get directly occurrences of product_id for thousands of rows.

You can use it!
var data = [{
id: 'CB2FD8B7-7E6D-4BF3-8E73-70D41FFBE451',
products: [{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6B7"}],
falconpay_api_response: null,
dhl_updated_by: null
},{
id: 'CB2FD8B7-7E6D-4BF3-8E73-70D41FFBE452',
products: [{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6B7"},{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6K7"}],
falconpay_api_response: null,
dhl_updated_by: null
},{
id: 'CB2FD8B7-7E6D-4BF3-8E73-70D41FFBE453',
products: [{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6K7"}],
falconpay_api_response: null,
dhl_updated_by: null
},{
id: 'CB2FD8B7-7E6D-4BF3-8E73-70D41FFBE454',
products: [{"product_id":"22061DA1-5D64-475A-B36A-140ECFE8D6B7"}],
falconpay_api_response: null,
dhl_updated_by: null
}];
var a =[];
data.forEach(function(order){
order.products.forEach(function(product){
if(a[product.product_id] == undefined){
a[product.product_id] = [];
}
a[product.product_id].push(order);
})
});
console.log(a);

Try the following Query (That's only works in JSON data type) :-
SELECT products->>'$.product_id' products,
count(products)
FROM events
GROUP BY products->>'$.product_id';
And Following Link will helpful to you :-
[http://www.mysqltutorial.org/mysql-json/]

Related

Query MongoDB Aggregation framework with Golang

I have in a collection stores , products and many prices (for store-products there are many prices) of the products in MongoDB
I have to find out min price from a product in a store in the last 30 days with the help of go
I have built the following aggregation pipeline
pipeline := []bson.M{
bson.D{
"$group", bson.D{
{
"_id", bson.D{
{
Key: "storeId",
Value: "$storeUd",
},
{
Key: "productId",
Value: "$productId",
},
},
},
minPrice : {
Key: "min",
Value: "$price",
},
},
} <---
}
But go compiler tell me in the line that I marked with an arrow (<---) there is a mistake
syntax error: unexpected newline in composite literal; possibly missing comma or }
I would like to calculate something like
select min(price)
from prices
group by storeId , productId
Please can you tell me what is wrong?
Thanks,
Aurel
I added }, but what I get you can see in the attached picture - the next declaration (var ... ) is in red ....

Get Empty Rows in TypeORM

I'm trying to write a typeORM query which includes multiple where clauses. I am able to achieve this via where option as follows:
const categories = [
{ name: 'master', categoryTypeId: 2, parentId: 1, locationId: null },
{ name: 'food', categoryTypeId: 3, parentId: null, locationId: null }];
const rows = await Repo.find({
where: categories.map((category) => ({
name: category.name,
categoryTypeId: category.categoryTypeId,
locationId: category.locationId
})),
});
I would want to maintain the mapping b/w the input array and the rows returned. For example, I know that the second category doesn't exist in the DB. I would want to have an empty object in the rows variable so that I know which categories didn't yield any result.
Upon research I have found that we can do something with SQL as mentioned here. But, I'm not sure how do I translate into typeORM if I can.

Handling Data on PostgreSQL for a comment thread app similar to Reddit

First time posting a question on here.
I am working with PostgreSQL and had a question on how to format data coming from a PostgreSQL DB. For practice, I am building a comment thread app similar to Reddit's. I organized my database in the following way
Post Table
CREATE TABLE Posts (
id serial PRIMARY KEY,
userId int,
header VARCHAR
)
Comment Table
CREATE TABLE Comments (
id serial PRIMARY KEY,
userId int,
commentText VARCHAR,
parentId int,
postId int
)
I want my end data to be an array of objects organized by postId with a comments key / value pair that stores all the comments for that postId (example below).
Should I format my data in this way using postgres queries, run sorting server side, or on client side? AND is this a conventional/efficient way of handling/formatting this kind of data? or am I missing some other way of organizing data for a comment thread?
Im use to working with MongoDb so not sure if my way of wanting to structure the data is due to working with mongoDb.
I would like for my data to look somewhat like this (unless there is a better more efficient way of doing it):
const posts = [
{
postId: 1,
header: 'Post Header',
comments: [
{
commentId: 1,
text: 'comment text',
parentId: null
},
{
commentId: 2,
text: 'comment text',
parentId: 1
}
]
},
{
postId: 2,
header: 'Post Header',
comments: [
{
commentId: 3,
text: 'comment text',
parentId: null
},
{
commentId: 2,
text: 'comment text',
parentId: 3
}
]
},
]
Thank you in advance!!
Postgres has a number of built-in ways to handle JSON: https://www.postgresql.org/docs/9.5/functions-json.html
Something like
SELECT
postID
,json_build_array(
json_build_object('commentId', id, 'text', commentText, 'parentId', parentId)
) as comments
FROM comments
GROUP BY postId
and then just join to the original Posts for metadata

How to filter on a json column for a specific value?

I'm on postgres and have a table orders with a data column which is jsonb. Here's a condensed example of data in one of them - they have UUID keys and a value of { id, value }
{
'36462bd9-4ffa-4ee3-9a04-c2eb7575fe6c': {
id: '',
value: '2020-04-20T01:32:14.017Z',
},
'9baaed61-1275-4bbc-ae4f-2994ec9f7fda': { id: '4', value: 'Paper Towels' },
}
How can I do operations such as to find any orders where data has some UUID (ie. 9baaed61-1275-4bbc-ae4f-2994ec9f7fda) and { id: '4' }?
You can use the contains operator #>
select *
from the_table
where data #> '{"9baaed61-1275-4bbc-ae4f-2994ec9f7fda": {"id": "4"}}';
This assumes that the invalid JSON id: '4' from your question is really stored as "id":"4". If the value is stored as a number: "id": 4 then you need to use that in the comparison value.

knex insert multiple rows

I have a problem inserting many rows into postgres db with knex.
I have dynamic number of rows needed to be inserted. The result i expect is:
insert row four times (four is for an example. I dont know exact number of inserts as it comes dynamically from frontend):
field_id will be diffrent in every row: (1,2,3,4) - i have array of these ID's
id_of_product will be always the same
value will be always diffrent: (req.body[id] that comes from Frontend) - ID in brackets is same value as the field_id from an
array
How i can achieve that? I tried looping it with forEach, but it's async operation so i can't use .then() as it will be called four times
Here's what i tried. i dont know how to set field_id and req.body to take it dynamically.
fields = [1,2,3,4]
Expected result:
knex creates 4 inserts as follows:
field_id: 1,
product_id: some static id
value: frontValue[1]
ETC
knex('metadata').insert(
[{ field_id: fields,
product_id: product_id,
value: req.body[fields]
}]
)
If I understand correctly you want to insert 4 records to your metadata table:
{ field_id: 1, product_id: X, value: req.body[1] },
{ field_id: 2, product_id: X, value: req.body[2] },
{ field_id: 3, product_id: X, value: req.body[3] },
{ field_id: 4, product_id: X, value: req.body[4] }
To insert multiple records in the same statement they each need to be separate elements in the array that you supply to Knex (check out the insert docs for additional examples):
const product_id = X;
const fieldsToInsert = fields.map(field =>
({ field_id: field, product_id, value: req.body[field] }));
return knex('metadata').insert(fieldsToInsert)
.then(() => { /* handle success */ })
.catch(() => { /* handle failure */});