Validate json format in prestoDB - json

We use presto JSON capabilities quit heavily and on thing the is missing for us is to be able to null when JSON is not a valid on this way SQL statement that use JSON functions will not break if there is a problem with the JSON format.
Initially I thought it can be done with some combination of JSON_PARSE and NULLIF but couldn't manage to pull this of..
is there a way to do make this kind of validation?
Thanks

You can use the try function to prevent the json functions from failing the query. For example, SELECT try(json_parse('bad json')) will return null instead of failing the query.

Related

MYSQL Json query

I have a JSON array of objects in a MySQL table that I am trying to see if there is a way to query and just pull the data. For example.
JSON Array Object
email_address_dump
[{"value":"a123#yahoo.com","type":"personal"},{"value":"all123#hotmail.com","type":"personal"},{"value":"car_sq5#indeedemail.com","type":"personal"}]
is there a way to query out just the email address? so that the results can be something like this?
a123#yahoo.com, all123#hotmail.com, car_sq5#indeedemail.com
I am not trying to search within the column, I know that with JSON Obtains you can use a where clause, this is more of a JSON Extract.
I was able to solve this by using JSON Extract from MySQL.
json_extract(c.email_address_dump, ''$[*].value') as EmailAddressArray,

Bookshelf: query builder: how to use like operator with json column?

I'm using bookshelf with postgresql database
Information is a column of type json.
I want to retrieve all column that are like '%pattern%'
With sql query i use
select * from table where information::text like '%pattern%';
I want to do that with bookshelf query builder
model.query(function(qb) {
qb.where('information', 'LIKE', '%pattern%')
}).fetch()
But it didn't work and i can't find how to do it in bookshelf docs
Any idea?
The tricky part here is, although you might think that JSON (and JSONB) columns are text, they aren't! So there's no way to do a LIKE comparison on one. Well, there is, but you'd have to convert it to a string first:
SELECT * FROM wombats WHERE information #>> '{}' LIKE '%pattern%';
which is a really terrible idea, please don't do that! As #GMB points out in the comments, JSON is a structured format that is far more powerful. Postgres is great at handling JSON, so just ask it for what you need. Let's say your value is in a JSON property named description:
SELECT * FROM wombats
WHERE (information->'description')::TEXT
LIKE '%pattern%';
Here, even though we've identified the correct property in our JSON object, it comes out as type JSON: we still have to cast it to ::TEXT before comparing it with a string using LIKE. The Bookshelf/Knex version of all this would look like:
model
.query(function(qb) {
const keyword = "pattern";
qb.whereRaw(`(information->'description')::TEXT LIKE '%${keyword}%'`)
})
.fetch();
Apparently this part of the raw query cannot be parameterized (in Postgres, at least) so the string substitution in JavaScript is required. This means you should be extra careful with where that string comes from (ie only use a limited subset, or sanitise before use) as you're bypassing Knex's usual protections.

Accessing data from JSON field in Postgres

I am working with a database which is using json as a data type in a Postgres DB and am having issues trying to extract values from the json document. I've done some researching around and have tried a variety of solutions including using
json_array_elements
response ->> 'filterEntryId'
json_populate_recordset(null::obj, table.column -> 'filterEntryId'
but have not been successful. I am starting to think that it is the way that the json is being stored in the column, ie that it starts with a '[' instead of a '{'.
Below is an example of the value of the json field.
[{
"filterEntryId":373,
"length":3,
"locale":"en",
"matched":"dog",
"quality":1.0,
"root":"dog",
"severity":"mild",
"start":2,
"tags":["Vulgarity"],
"type":"blacklist"
}]
Just figured it out. I was mis-using the json_array_elements function.
In the event that anyone stumbles across this, here is the correct way to query the json
select
json_array_elements(column) ->> 'filterEntryId'
from table
Essentially you are first accessing the document and then grabbing what you need from it. I think this had to be done this way due to the '[' around the data in the column.
Feel free, anyone, to expand on my explanation.

JSON schema- Timestamp validation

I am trying to create a Json schema regex to have a timestamp validation in milliseconds. Eg.20140508172846.127.
I tried like this Pattern:^[0-9] it's not working. please suggest any other way to perform timestamp validation.
You should use a regex. The problem is the pattern you provided does not match floating point numbers.
You could try with:
(\d+(?:\.\d*)?|\.\d+)\s+(\S+)
But you would need to specify exactly which timestamps values are allowed (and you will find for sure an answer in stackoverflow)

MySQL increment value in a text field

Say I have a text field with JSON data like this:
{
"id": {
"name": "value",
"votes": 0
}
}
Is there a way to write a query which would find id and then would increment votes value?
I know i could just retrieve the JSON data update what I need and reinsert updated version, but i wonder is there a way to do this without running two queries?
UPDATE `sometable`
SET `somefield` = JSON_REPLACE(`somefield`, '$.id.votes', JSON_EXTRACT(`somefield` , '$.id.votes')+1)
WHERE ...
Edit
As of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON documents.
JSON_EXTRACT will allow you to access a particular JSON element in a JSON field, while JSON_REPLACE will allow you to update it.
To specify the JSON element you wish to access, use a string with the format
'$.[top element].[sub element].[...]'
So in your case, to access id.votes, use the string '$.id.votes'.
The SQL code above demonstrates putting all this together to increment the value of a JSON field by 1.
I think for a task like this you're stuck using a plain old SELECT followed by an UPDATE (after you parse the JSON, increment the value you want, and then serialize the JSON back).
You should wrap these operations in a single transaction, and if you're using InnoDB then you might also consider using SELECT ... FOR UPDATE : http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
This is sort of a tangent, but I thought I'd also mention that this is the type of operation that a NoSQL database like MongoDB is quite good at.