UPDATE tab s
SET s.DATA = json_transform(DATA, REPLACE '$.dataFilterDefn.columns[1]' = (SELECT JSON_ARRAYAGG(JSON FORMAT JSON RETURNING CLOB)
FROM
(SELECT JSON
FROM
(SELECT j.json || ',' || JSON AS json
FROM tab d
CROSS APPLY JSON_TABLE(d.tab, '$.dataFilterDefn.columns[1]' COLUMNS(json CLOB FORMAT JSON PATH '$')) j
WHERE d.UID = 252))));
The data look like this:
"columns":[
{
"label":"Subcategory",
"aggFn":"NONE",
"datasetId":"ADVENTURE_WORKS",
"fieldName":"SUB_CAT",
"id":"FILTER-1"
}
]
My expectation:
"columns":[
{
"label":"Subcategory",
"aggFn":"NONE",
"datasetId":"ADVENTURE_WORKS",
"fieldName":"SUB_CAT",
"id":"FILTER-1"
},
{
"label":"Subcategory",
"aggFn":"NONE",
"datasetId":"ADVENTURE_WORKS",
"fieldName":"SUB_CAT",
"id":"FILTER-1"
}
]
I want the columns data should duplicate.The columns value will be different.It"ll not be the same. I need to update the column values dynamically..It should not be hardcoded. How can I achieve this in json using Oracle version 19c?
Using json_transform you can append items to an array. Using json_query you can extract the first element of the array.
So you can do something like this:
with rws as (
select '{ "columns":[
{
"label":"Subcategory",
"aggFn":"NONE",
"datasetId":"ADVENTURE_WORKS",
"fieldName":"SUB_CAT",
"id":"ART-DATA-FILTER-1"
}
] }' jdata
from dual
)
select json_transform (
jdata,
append '$.columns' = json_query ( jdata, '$.columns[0]' )
returning varchar2 pretty
)
from rws r;
{
"columns" :
[
{
"label" : "Subcategory",
"aggFn" : "NONE",
"datasetId" : "ADVENTURE_WORKS",
"fieldName" : "SUB_CAT",
"id" : "ART-DATA-FILTER-1"
},
{
"label" : "Subcategory",
"aggFn" : "NONE",
"datasetId" : "ADVENTURE_WORKS",
"fieldName" : "SUB_CAT",
"id" : "ART-DATA-FILTER-1"
}
]
}
Note that json_transform was only added in a recent release update, so ensure your 19c version is fully patched and up-to-date.
Related
In mongodb I'm wondering how you can properly insert json to the db from the command line with an object that contains an object?
db.burgers.insert(
[
{'burger': {
'patty': 'beef',
'cheese': false,
'toppings': [
'ketchup', 'onions', 'pickles'
]
}}
]
)
When I try the code above, db.burgers.burger.find() returns 0, when I am expecting it to return 1
The following is how they get returned.
db.burgers.find().pretty()
{
"_id" : ObjectId("5f87b58afd426d861d55b5ff"),
"burger" : {
"patty" : "beef",
"cheese" : false,
"toppings" : [
"ketchup",
"onions",
"pickles"
]
}
}
In mongodb I'm wondering how you can properly insert json to the db
from the command line with an object that contains an object?
Your inserting the document into the collection is correct. You can use insertOne, insertMany or insert methods to insert documents. The insertOne is specific for insert one document at a time. insert and insertMany can be used to insert one or more documents at a time.
From the command line, mongo shell:
> var doc = { 'burger': {
'patty': 'beef',
'cheese': false,
'toppings': [ 'ketchup', 'onions', 'pickles' ]
} }
> db.burgers.insertOne(doc)
{
"acknowledged" : true,
"insertedId" : ObjectId("5f87f68dd039d5cb61ae2251")
}
Note the _id field is created by the MongoDB.
You can use insertMany to insert many documents - an array of JSON documents. For example,
var docs_array = [ {... }, {... }, ... ]
db.burgers.insertMany(docs_array)
When I try the code above, db.burgers.burger.find() returns 0, when I
am expecting it to return 1
You can query the document using the find or findOne methods. The find returns a cursor (with multiple documents) and the findOne always returns one document (or a null if no document is found). For example:
> db.burgers.findOne()
> db.burgers.findOne( { _id: ObjectId("5f87f68dd039d5cb61ae2251") } )
The above queries return the newly inserted document, above.
Your query db.burgers.burger.find() is not correct, I think. If you want only the burger field ( this a nested document) to be printed, then use projection, like this:
> db.burgers.findOne( {}, { burger: 1, _id: 0 } )
{
"burger" : {
"patty" : "beef",
"cheese" : false,
"toppings" : [
"ketchup",
"onions",
"pickles"
]
}
}
Note the projection allows output only the specific fields, and exclude others. In the above query, the _id field is excluded.
If you want to count documents in the collection use this:
> db.burgers.countDocuments({})
Reference:
Insert
Documents
Query
Documents
Query on Nested
Documents
I've found the flatten function but the example is simpler than my real example. It can be created with the following code:
create or replace table test2 as
select '5dd17ef333de385a360e0ef1' as id,
parse_json('{
"_id" : "5dd17ef333de385a360e0ef1",
"uid" : "5dd175d3333b85961df27c51",
"task_info" : {
"reps=1" : [
[
{
"cached" : false,
"transform max RAM" : 51445000,
}
],
[
{
"cached" : false,
"transform max RAM" : 51445000,
}
],
[
{
"cached" : true,
"transform max RAM" : 51445000,
}
]
]
}
}')::variant as json_rec
;
Then my attempt to parse it:
select id
, json_rec:_id::string(100) as extracted_id
, value:cached::string as cached
, value
, json_rec
from
test2
, lateral flatten( input => json_rec:task_info )
;
The cached is clearly not going deep enough, although I am unclear of the syntax that is required to fish something like these values out. Thoughts?
If what you want is a separate row for each of the items in the innermost array (i.e. 3 rows for the above example), then you can use recursive=>true and filter on key='cached', like this:
select id
, json_rec:_id::string(100) as extracted_id
, value as cached
, json_rec
from
test2
, lateral flatten( input => json_rec:task_info, recursive=>true)
where key='cached';
I'm trying to select all objects in my database which are between two dates.
Problem is: Dates are inside of an array
Already tried using both Robo 3T and Studio 3T with SQL, with no sucess.
{
"_id" : "5d9b703fe1bc4f138c5977b5",
"Number" : 112795,
"Finalizations" : [
{
"Value" : "89.95",
"Portions" : [
{
"Expiration" : ISODate("2019-11-06T02:00:00.000Z"),
"Value" : "89.95"
}
]
}
]
}
I need to return all the objects that have an "Expiration" between 11/01 and 11/25.
Assuming your collection is called mycollection you can query using the mongo shell...
db.mycollection.find(
{
"Finalizations.Portions.Expiration": {"$gte": ISODate("2019-11-01")},
"Finalizations.Portions.Expiration": {"$lt": ISODate("2019-11-25")}
}
)
I have JSON values like this stored in a table:
{
"properties":[
{
"address":{
"value":"A3",
"name":"",
"prop":"",
"path":[
"RealOptionsList9293"
],
"type":"local"
},
"value":{
"type":11,
"value":"portland"
},
"dependents":[
],
"save":true
}
]
}
I'd like to index on address.value and value.value so that I can query on them. MSDN examples are for basic property using computed column. It does not cover indexing an array. Is indexing possible on array? Any example will be helpful.
I'd like to query for rows with:
JSON_VALUE(mycolumn, '$.properties[*].address.value') = 'A3'
AND JSON_VALUE(mycolumn, $.properties[*].value.value) = 'portland'
I don't see [*] syntax. Should I use OPENJSON() instead? If I use it, should I use a materialized view?
If you want to query a JSON array, OPENJSON() is more appropriate:
Table:
CREATE TABLE #Data (
JsonData nvarchar(max)
)
INSERT INTo #Data (JsonData)
VALUES (N'{
"properties":[
{
"address":{
"value":"A3",
"name":"",
"prop":"",
"path":[
"RealOptionsList9293"
],
"type":"local"
},
"value":{
"type":11,
"value":"portland"
},
"dependents":[
],
"save":true
},
{
"address":{
"value":"A4",
"name":"",
"prop":"",
"path":[
"RealOptionsList9293"
],
"type":"local"
},
"value":{
"type":11,
"value":"portland"
},
"dependents":[
],
"save":true
}
]
}')
Statement:
SELECT d.*
FROM #Data d
CROSS APPLY OPENJSON(d.JsonData, '$.properties') WITH (
AddressValue nvarchar(1000) '$.address.value',
ValueValue nvarchar(1000) '$.value.value'
) j
WHERE j.AddressValue = 'A3' AND ValueValue = 'portland'
When you want to query JSON arrays or objects you should use JSON_QUERY which is designed to work with that. JSON_VALUE is designed to return a scalar, thus, if you use JSON_VALUE with address, value or even dependents (in your JSON), it'll always returns null. But if you use it with save, it'll return its value.
So, what you need to do is something like this :
SELECT
JSON_VALUE([Address],'$.value')
FROM (
SELECT
JSON_QUERY(#json,'$.properties[0].address') AS [Address]
, JSON_QUERY(#json,'$.properties[0].value') AS [Value]
, JSON_QUERY(#json,'$.properties[0].dependents') AS [dependents]
) arrays
Below is MongoDB document.
`{
"_id" : ObjectId("588f09c8d466d7054114b456"),
"phonebook" : [
{
"pb_name_first" : "Aasu bhai",
"pb_phone_number" : [
{
"ph_id" : 2,
"ph_no" : "+91111111",
"ph_type" : "Mobile"
}
],
"pb_email_id" : [
{
"email_id" : "temp#gmail.com",
"email_type" : "Home",
"em_id" :1
},
{
"email_id" : "test#gmail.com",
"email_type" : "work",
"em_id" :2
}
],
"pb_name_prefix" : "MR."
}
]
}`
I want mongodb query that will update email_id data in pb_email_id array on basis of em_id. If i select em_id=1 then that record temp#gmail.com will update.if i select em_id=2 then test#gmail.com will update.
I don't think you can apply if-else logic in update call, you can run two separate update calls
db.collection.update({'pb_email_id.em_id':1},{$set : {'pb_email_id.$.email_id' : 'temp#gmail.com'}},{multi:true});
db.collection.update({'pb_email_id.em_id':2},{$set : {'pb_email_id.$.email_id' : 'test#gmail.com'}},{multi:true});
However you can run a script on collection to apply multiple logic
db.collection.find({}).forEach(function(doc){
if(doc.pb_email_id && doc.pb_email_id.length>0){
for(var i in doc.pb_email_id){
if(doc.pb_email_id[i].em_id === 1){
doc.pb_email_id[i].email_id = "temp#gmail.com"}
else if(doc.pb_email_id[i].em_id === 2){doc.pb_email_id[i].email_id = "test#gmail.com"}
db.collection.save(db)
}
}
})
If you have to apply multiple logic, you can run script, otherwise two update calls if that's as much as needed.
P.S - since you didn't mentioned collection name, I used db.collection.update it should be collection name like db.phonebook.find etc.