How to query JSON array in MYSQL with AND - mysql

If i have json like the following in a column in a mysql database
[
{
"name": "John",
"checked": true
},
{
"name": "Lucy",
"checked": false
}
]
how can I select in mysql all rows where in the same object name = 'John' and checked = true.
The json objects may have more keys and keys may not be in a specific order.

Just use JSON_CONTAINS:
SELECT * from `users`
WHERE JSON_CONTAINS(`data`, '{"name": "John","checked": true}');

You can try to match the string if the keys are always in the same order. Assuming your column is called people
SELECT
IF(people LIKE '%[
{
\"name\": \"John\",
\"checked\": true%', TRUE, FALSE) AS 'john_checked'
FROM table
WHERE (people LIKE '%[
{
\"name\": \"John\",
\"checked\": true%')
With the knowledge of this solution, you could create a shorter SQL such as the following. You may use this alone, or use it as a subquery within the where clause of a query that will return all the rows.
SELECT
IF(people LIKE '%\"checked\": true%', TRUE, FALSE) AS 'john_checked'
FROM table
WHERE (people LIKE '%\"name\": \"John\"%')
You can probably see in this that JSON is not ideal for storing in mySQL.
The better solution is to design your database as a relational one, i.e. have an additional table called people and a column(s) that link the data. Saying how to design this would require me to know much more about your data/subject, but you should learn about SQL "joins" and normalisation.
There are other questions that discuss JSON in mySQL, such as Storing JSON in database vs. having a new column for each key and Storing Data in MySQL as JSON
As of mySQL 5.7 there are some json related functions. See this wagon article, and the mySQL documentation.

Here is how it can be done in postgresql:
create table users (data jsonb);'
insert into users values ('[{"name": "John", "checked": "true"}, {"name": "Lucy", "checked": "false"}]'),('[{"name": "John", "checked": "false"}, {"name": "Lucy", "checked": "false"}]'),('[{"name": "John", "checked": "false"}, {"name": "Lucy", "checked": "true"}]');
select * from users, jsonb_array_elements(users.data) obj
where obj->>'name' = 'John' and obj->>'checked' = 'true';
data | value
-----------------------------------------------------------------------------+-------------------------------------
[{"name": "John", "checked": "true"}, {"name": "Lucy", "checked": "false"}] | {"name": "John", "checked": "true"}
(1 row)

Related

mySQL JSON Document Store method for inserting data into node 3 levels deep

I want to take the data from here: https://raw.githubusercontent.com/usnistgov/oscal-content/master/examples/ssp/json/ssp-example.json
which I've pulled into a mySQL database called "ssp_models" into a JSON column called 'json_data', and I need add a new 'name' and 'type' entry into the 'parties' node with a new uuid in the same format as the example.
So in my mySQL database table, "ssp_models", I have this entry: Noting that I should be able to write the data by somehow referencing "66c2a1c8-5830-48bd-8fdd-55a1c3a52888" as the record to modify.
All the example I've seen online seem to force me to read out the entire JSON into a variable, make the addition, and then cram it back into the json_data column, which seems costly, especially with large JSON data-sets.
Isn't there a simple way I can say
"INSERT INTO ssp_models JSON_INSERT <somehow burrow down to 'system-security-plan'.metadata.parties (name, type) VALUES ('Raytheon', 'organization') WHERE uuid = '66c2a1c8-5830-48bd-8fdd-55a1c3a52888'
I was looking at this other stackoverflow example for inserting into JSON:
How to create and insert a JSON object using MySQL queries?
However, that's basically useful when you are starting from scratch, vs. needing to add JSON data to data that already exists.
You may want to read https://dev.mysql.com/doc/refman/8.0/en/json-function-reference.html and explore each of the functions, and try them out one by one, if you're going to continue working with JSON data in MySQL.
I was able to do what you describe this way:
update ssp_models set json_data = json_array_append(
json_data,
'$."system-security-plan".metadata.parties',
json_object('name', 'Bingo', 'type', 'farmer')
)
where uuid = '66c2a1c8-5830-48bd-8fdd-55a1c3a52888';
Then I checked the data:
mysql> select uuid, json_pretty(json_data) from ssp_models\G
*************************** 1. row ***************************
uuid: 66c2a1c8-5830-48bd-8fdd-55a1c3a52888
json_pretty(json_data): {
"system-security-plan": {
"uuid": "66c2a1c8-5830-48bd-8fdd-55a1c3a52888",
"metadata": {
"roles": [
{
"id": "legal-officer",
"title": "Legal Officer"
}
],
"title": "Enterprise Logging and Auditing System Security Plan",
"parties": [
{
"name": "Enterprise Asset Owners",
"type": "organization",
"uuid": "3b2a5599-cc37-403f-ae36-5708fa804b27"
},
{
"name": "Enterprise Asset Administrators",
"type": "organization",
"uuid": "833ac398-5c9a-4e6b-acba-2a9c11399da0"
},
{
"name": "Bingo",
"type": "farmer"
}
]
}
}
}
I started with data like yours, but for this test, I truncated everything after the parties array.

Azure Cosmos DB - how to retrieve json attributes from a document similar like retrieving column names from SQL table

{
"Volcano Name": "Agua de Pau",
"Country": "Portugal",
"Region": "Azores",
"Location": {
"type": "Point",
"coordinates": [
-25.47,
37.77
]
},
"Elevation": 947,
"Type": "Stratovolcano",
"Status": "Historical",
"Last Known Eruption": "Last known eruption from 1500-1699, inclusive",
"id": "d44c94b6-81f8-4b27-4970-f79b149529d3",
"_rid": "Sl8fALN4sw4BAAAAAAAAAA==",
"_ts": 1448049512,
"_self": "dbs/Sl8fAA==/colls/Sl8fALN4sw4=/docs/Sl8fALN4sw4BAAAAAAAAAA==/",
"_etag": "\"0000443f-0000-0000-0000-564f7b680000\"",
"_attachments": "attachments/"
}
In MS SQL, we have like below to read column names from a table.
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS
where table_name = 'table_name' .
I am expecting the same for document db. is it possible
from the above sample document which has the Type "Stratovolcano" to retrieve the json names "Volcano Name", "Country", "Region", "Location"... etc
An Azure Cosmos SQL container is a schema-agnostic container of items. The items in a container can have arbitrary schemas unlike rows in a table. So, Cosmos DB will not be able to do what you are asking for.
In your case it looks like all your items will have the same schema. So, you could do a " select * from c where c.id = "someid" " and infer the schema from the retuned item.

MySQL join json

To avoid using temporary tables, I hoped to store some data as a json array within a variable and join on it. The data looks something like this:
[
{
"CarID": "9",
"Tank": "11.4",
"Distance": "120",
"From": "Brussels",
"To": "Bruges"
},
{
"CarID": "22",
"Tank": "15.9",
"Distance": "70",
"From": "Eupen",
"To": "Cologne"
}
]
I would like to set a variable in mysql to that value and be able to do something like the following:
SELECT
(
Cars.Consumption
* JSON_UNQUOTE(JSON_something('???','$.Distance'))
) - JSON_UNQUOTE(JSON_something('???','$.Tank')) AS neededRefuel
FROM Cars
WHERE JSON_SEARCH(
#myJson,
'one',
CAST(Cars.CarID AS JSON),
NULL,
'$[*].CarID'
) IS NOT NULL
This is just a simplified example.
Apparently json values as integer are not easy to detect in mysql, so I set quotes.
I wanted to use this kind of filter within a view, so temporary tables are not really an option.
Using MySQL 8.0.11
I just humbled upon JSON_TABLE and it seems to do exactly what I want :)

How to query MySQL Json Array

A MySQL table has a JSON column containing a large amount of JSON data.
For example:
SELECT nodes From Table LIMIT 1;
results in:
'{"data": {"id": "Node A", "state": true, "details": [{"value": "Value","description": "Test"}, {"value": "Value2", "description": "Test2"}, {"value": "Value 7", "description": "Test 7"}, {"value": "Value 9", "description": "Test 9"}]}}'
How can I write queries that return rows in accordance with the following examples:
Where Node A state is True. In this case "Node A" is the value of key "id" and "state" contains True or False.
Where "value" is "Value2" or where "description" is "Test2." Note that these values are in a list that contains key value pairs.
I doubt if you can make a direct MySQL query to achieve above task. You will have to load all the string data from MySQL db then parse this string to get JSON object upon which you can perform your custom query operation to get your output.
But here in this case i will suggest you to use MongoDB which will be an ideal database storage solution and you can make direct queries.

How can I add a Mongo Query inside one Document and insert it in a Collection?

This a sample document. I wish to insert a MongoDB query in the field "condition".
So how to insert it?
{
"_id": 9000001,
"GeoId": 111002,
"collection": "Age",
"condition": "{ db.age.find({"Fields.FieldValue" : ""})}",
"alertMessageTemplate": "The age is #<20# & #>100# ",
}
My best approach will be collection name and condition is separate fields:
"collection": "Age",
"condition": {"Fields.FieldValue" : ""},
This way you can save condition as a JSON object.
Then you can format on find: db.getCollection('+collection+').find('+condition+');