I have a column in the users table of my Postgres dB table that is named email_subscription_prefs, which stores some some information in JSON format. It has an array_length of 1.
Sample Data:
[{"marketing":true,"transactional":true,"collaboration":true,"legal":true,"account":true}]
Issue:
I am trying to use bookshelf.js ORM to query and search all records in this table based on the value of the marketing key, specifically when its valueis true.
Here is an edited snippet of my code showing what I'm trying to implement this query using bookshelf.js:
return new User()
qb.where(function() {
this.where('domicile', 'USA').orWhere('domicile', null)
})
qb.whereRaw('cast(email_subscription_prefs->>? as boolean) = ?', ['marketing', true])
qb.limit(100)
})
Can someone tell me what I'm doing wrong on qb.whereRaw statement where I'm trying to query the JSON column email_subscription_prefs?
The code returns nothing where there are several thousands records in the users table.
Thanks in advance.
You seem to have an array of objects in sample data instead of single json object.
[
{
"marketing":true,
"transactional":true,
"collaboration":true,
"legal":true,
"account":true
}
]
so looks like you are trying to refer email_subscription_prefs->>'marketing' which is not found from the array.
To fetch marketing attribute of the first item in the array you should do:
email_subscription_prefs->0->>'marketing'
If that is not the problem, then you would need to add some example data from your DB to be able to tell what is the problem. You current description doesn't describe the queried table well enough.
Related
I have ran a crawler on json S3 file for updating an existing external table.
Once finished I checked the SVL_S3LOG to see the structure of the external table and saw it was updated and I have new column with Array<int> type like expected.
When I have tried to execute select * on the external table I got this error: "Invalid operation: Nested tables do not support '*' in the SELECT clause.;"
So I have tried to detailed the select statement with all columns names:
select name, date, books.... (books is the Array<int> type)
from external_table_a1
and got this error:
Invalid operation: column "books" does not exist in external_table_a1;"
I have also checked under "AWS Glue" the table external_table_a1 and saw that column "books" is recognized and have the type Array<int>.
Can someone explain why my simple query is wrong?
What am I missing?
Querying JSON data is a bit of a hassle with Redshift: when parsing is enabled (eg using the appropriate SerDe configuration) the JSON is stored as a SUPER type. In your case that's the Array<int>.
The AWS documentation on Querying semistructured data seems pretty straightforward, mentioning that PartiQL uses "dotted notation and array subscript for path navigation when accessing nested data". This doesn't work for me, although I don't find any reasons in their SUPER Limitations Documentation.
Solution 1
What I have to do is set the flags set json_serialization_enable to true; and set json_serialization_parse_nested_strings to true; which will parse the SUPER type as JSON (ie back to JSON). I can then use JSON-functions to query the data. Unnesting data gets even crazier because you can only use the unnest syntax select item from table as t, t.items as item on SUPER types. I genuinely don't think that this is the supposed way to query and unnest SUPER objects but that's the only approach that worked for me.
They described that in some older "Amazon Redshift Developer Guide".
Solution 2
When you are writing your query or creating a query Redshift will try to fit the output into one of the basic column data types. If the result of your query does not match any of those types, Redshift will not process the query. Hence, in order to convert a SUPER to a compatible type you will have to unnest it (using the rather peculiar Redshift unnest syntax).
For me, this works in certain cases but I'm not always able to properly index arrays, not can I access the array index (using my_table.array_column as array_entry at array_index syntax).
I wish to know how I can use postgres returning clause with SQL Boiler elegantly.
For example I wish to update some object by some fields and return the object id:
err = queries.RawG(`update users
set name='test-name'
WHERE email='test#example.com'
RETURNING id`).Bind(ctx, boil.GetDB(), &user)
The following is working as expected, the user column has been updated and I got back the user id, but I'm looking for more elegant ways to do the same without using queries.RawG
I have created one table with JSONB column as "data"
And the sample value of that column is
[{field_id:1, value:10},{field_id:2, value:"some string"}]
Now there are multiple rows like this..
What i want ?
I want to use aggregate function on "data" column such that, i should
get
Sum of all value where field_id = 1;
Avg of value where field_id = 1;
I have searched alot on google but not able to find a proper solution.
sometimes it says "Field doesn't exist" and some times it says "from clause missing"
I tried referring like data.value & also data -> value lastly data ->> value
But nothing is working.
Please let me know the solution if any one knows,
Thanks in advance.
Your attributes should be something like this, so you instruct it to run the function on a specific value:
attributes: [
[sequelize.fn('sum', sequelize.literal("data->>'value'")), 'json_sum'],
[sequelize.fn('avg', sequelize.literal("data->>'value'")), 'json_avg']
]
Then in WHERE, you reference field_id in a similar way, using literal():
where: sequelize.literal("data->>'field_id' = 1")
Your example also included a string for the value of "value" which of course won't work. But if the basic Sequelize setup works on a good set of data, you can enhance the WHERE clause to test for numeric "value" data, there are good examples here: Postgres query to check a string is a number
Hopefully this gets you close. In my experience with Sequelize + Postgres, it helps to run the program in such a way that you see what queries it creates, like in a terminal where the output is streaming. On the way to a working statement, you'll either create objects which Sequelize doesn't like, or Sequelize will create bad queries which Postgres doesn't like. If the query looks close, take it into pgAdmin for further work, then try to reproduce your adjustments in Sequelize. Good luck!
My postgres database table has a column location which is character varying[]. In my nestjs entity of the table I have following for the location column-
#Column("character varying",{array:true})
location: string[];
What I am trying to do is search the rows having passed parameter as locations.
This is the raw query which is giving me appropriate results-
select * from blogs where language #> '{"Spanish","English"}'
In my nestjs service, how can I achieve the above query?
I tried doing this-
return await this.blogsRepo.find({
where: [
{
location: Any(body.locations)
}
]
})
body.locations is an array like this-
body.locations = ["Spanish","English"]
The above typeorm solution gives me following error-
'could not find array type for data type character varying[]'
What could be the possible solution for this? I will love a typeorm solution as I have kept raw query execution as my last option.
Thanks in advance,
You could try this:
await this.blogsRepo.find({
where: `${body.locations} = ANY (location)`,
});
As per the typeorm documentations, there is no way/ built in typeorm operator equivalent to #> operator.
So the only way to achieve what I wanted is to generate an entire query and then execute it using Repository.query() method.
Seems to work so far!
Select query doesn't work for JSON in OrientDB. Can someone provide with a working example showcasing two things:
Inserting JSON data correctly
Querying JSON data
Thanks!
1.Use "content" to implement JSON insert.
For Example-
insert into Person content {"name":"nawab","age":25}
for this to run,you must have prior configuration as-
1.Create a Vertex by-
create class Person extends V
2.Then Create Property name and age
create property Person.name string
create property Person.age integer
Here you go! I have been trying to figure this out for a while now and finally got it to work. :)
Run the following sql commands as displayed:
create class EXAMPLE
/* The trick is: Do not 'CREATE' the property with any type */
insert into EXAMPLE (my_prop) values ({"name": "James", "age": 23})
insert into EXAMPLE (my_prop) values ({"name": "Harden", "age": 24})
/* Fetch the fields inside the JSON */
select my_prop.name from example
select my_prop.age from example where my_prop.name like 'James'
I read this example from the book: Getting Started with OrientDB By Claudio Tesoriero
Hope it helps!
This question continues in the OrientDB group here. Have you tried if everything work?