I have this kind of json array and i want to check stringValue inside value array is null or not plus i want to check it with its id and fielddata is column name
[
{
"name": "50a5613e97e04cb5b8d32afa8a9975d1",
"value": {
"stringValue": null
}
},
{
"name": "bb127e8284c84692aa217539c4312394",
"value": {
"dateValue": 1549065600
}
}
]
query is:
select *
from field
WHERE (fielddata->>'name') = '50a5613e97e04cb5b8d32afa8a9975d1'
AND fielddata->'value'->>'stringValue' IS NOT NULL;
and I want use this query in laravel5.7
Try this
$result = \DB::table('field')->where('name', "50a5613e97e04cb5b8d32afa8a9975d1" )->where('value', $stringValue)->get();
if(isset($result)){
foreach($result as $res){
if(isset($res['value']->stringValue)){
// not null case
}else{
// null case
}
}
}
Within a SQL query, I think you want something like this:
select t.*
from the_table t
where exists (select *
from jsonb_array_elements(t.fielddata) as j(e)
where e ->> 'name' = '50a5613e97e04cb5b8d32afa8a9975d1'
and e -> 'value' ->> 'stringValue' is not null);
The exists sub-query will check every array element and see if at least one element has the specified name and a non-null stringValue. The query will then return the complete row from the table that fulfills the condition.
Online example: https://rextester.com/AGGJNR88809
Related
In my PostgreSQL 11.6 table I have a json field app_settings with data on the following format:
{
"my_app": {
"features": {
"very_good_feature": true,
"awesome_feature": false,
"even_better_feature": true
}
}
}
I want to create a query that selects a list of feature names where the feature has the value true. So in the example above, I would like the result of the query simply to be 2 rows like this:
very_good_feature
even_better_feature
I can successfully select ALL the keys with the following query:
select
json_object_keys(app_settings ->'my_app' -> 'features') as k
from
my_table;
How can I write the where clause to only list the ones with true as value?
try with json_each_text:
select j.* from my_table
join lateral json_each_text(app_settings->'my_app'->'features') j(k, v) on true
where
j.v = 'true'
I have a SQL table called 'Interactions' and a column called Events that holds an array of JSON data. I am looking for any row where the Events json has any array with #odata.type = #Sitecore.XConnect.Goal
[
{
"#odata.type":"#Sitecore.XConnect.Collection.Model.PageViewEvent",
"CustomValues":[
],
"DefinitionId":"9326cb1e-cec8-48f2-9a3e-91c7dbb2166c",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"Id":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2206225Z",
"ItemLanguage":"en",
"ItemVersion":1,
"Url":"/renewal-confirmation",
"SitecoreRenderingDevice":{
"Id":"fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
"Name":"Default"
}
},
{
"#odata.type":"#Sitecore.XConnect.Goal",
"CustomValues":[
],
"DataKey":"/sitecore/content/Client/home/renewal-confirmation",
"DefinitionId":"c0bc91b9-b5fc-4faa-bc12-3dba8bbae44f",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"EngagementValue":100,
"Id":"e7031fb4-ce57-459f-a9f1-2682748d3431",
"ParentEventId":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2518732Z"
}
]
What I am currently trying is this, but no results
select *
from [Interactions] I
where exists
(
select *
from openjson(I.Events,'$."#odata.type"')
where value = '#Sitecore.XConnect.Goal'
)
If I use this, I can get any row where the 1st item in the array #odata.type = #Sitecore.XConnect.Goal. This works. But I want it from any item in the array.
SELECT *
FROM [Interactions]
WHERE JSON_VALUE([Events], '$[0]."#odata.type"') = '#Sitecore.XConnect.Goal'
One possible approach is to parse the JSON column using OPENJSON() with explicit schema (WITH clause with columns definitions). With this approach you can filter the Interactions table and get information from the JSON data.
Table:
CREATE TABLE Interactions (
Events nvarchar(max)
)
INSERT INTO Interactions
(Events)
VALUES
(N'[
{
"#odata.type":"#Sitecore.XConnect.Collection.Model.PageViewEvent",
"CustomValues":[
],
"DefinitionId":"9326cb1e-cec8-48f2-9a3e-91c7dbb2166c",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"Id":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2206225Z",
"ItemLanguage":"en",
"ItemVersion":1,
"Url":"/renewal-confirmation",
"SitecoreRenderingDevice":{
"Id":"fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
"Name":"Default"
}
},
{
"#odata.type":"#Sitecore.XConnect.Goal",
"CustomValues":[
],
"DataKey":"/sitecore/content/Client/home/renewal-confirmation",
"DefinitionId":"c0bc91b9-b5fc-4faa-bc12-3dba8bbae44f",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"EngagementValue":100,
"Id":"e7031fb4-ce57-459f-a9f1-2682748d3431",
"ParentEventId":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2518732Z"
}
]')
Statement:
SELECT *
FROM Interactions i
CROSS APPLY OPENJSON(i.Events) WITH (
ODataType nvarchar(100) '$."#odata.type"'
-- and additional columns definitions
) j
WHERE j.ODataType = '#Sitecore.XConnect.Goal'
Your original query is close but doesn't work because you can't directly pick out scalars with OPENJSON. You want something like this:
SELECT *
FROM [interactions]
WHERE EXISTS (
SELECT 1
FROM OPENJSON([events]) WITH (
[#odata.type] NVARCHAR(MAX)
)
WHERE [#odata.type] = '#Sitecore.XConnect.Goal'
)
I'm trying to SELECT objects base on the roles property values.
Example: Select all names where role is 1 //response would return danny
Query Statement:
SELECT JSON_EXTRACT(username,'$[*].name') FROM objects WHERE JSON_CONTAINS(username,'1','$[*].roles')
COLUMN: username (JSON)
[
{
"name":"jordan",
"roles":[1,2,5]
},
{
"name":"danny",
"roles":[1,4]
}
]
Question: Why isn't my statement returning just the first object containing the name danny?
Try the following:
SELECT *
FROM objects
WHERE JSON_CONTAINS(components, '1', '$.roles');
In my situation, entreprise(company) can have several sites(filiales), I want to get all the filiales with format array.
In the json entreprise(company), there is no information of sites(filiales), In the json sites(filiales), it has entreprise(company) uid.
Json entreprise(company):
{
"type": "entreprise",
"dateUpdate": 1481716305279,
"owner": {
"type": "user",
"uid": "PNnqarPqSdaxmEJ4DoMv-A"
}
}
Json sites(filiales):
{
"type": "site",
"entreprise": {
"uid": "3c0CstzsTjqPdycL5yYzJQ",
"type": "entreprise"
},
"nom": "test"
}
The query I tried:
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (SELECT d.* FROM default d WHERE d.type = "site" AND d.entreprise.uid = uid) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise";
Result: error
{
"code": 5010,
"msg": "Error evaluating projection. - cause: FROM in correlated subquery must have USE KEYS clause: FROM default."
}
Then i use alias:
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (SELECT d.* FROM default d WHERE d.type = "site" AND d.entreprise.uid = META(entreprise).id) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise";
Result: sites array is empty.
First you have to create an index on your site documents :
CREATE INDEX site_ent_idx ON default(entreprise.uid) WHERE type="site";
Then change your query to use the new index :
SELECT
META(entreprise).id as uid,
ARRAY s FOR s IN (
SELECT site.*
FROM default as ent USE KEYS META(entreprise).id
JOIN default as site ON KEY site.entreprise.uid FOR ent
) END as sites,
entreprise.*
FROM default entreprise
WHERE entreprise.type = "entreprise"
This solution should meet your needs.
You need to perform an index join from sites to enterprises. See https://dzone.com/articles/join-faster-with-couchbase-index-joins
After that, use GROUP BY and ARRAY_AGG() to collect the sites into arrays.
The json column "data" contains value like
{"avatar":"kiran1454916822955.jpg","name":"shanthitwos charmlyi"}
I want to concatenate images/profiles/uploads/ for all the json key avatar.
I tried
UPDATE activity SET data->'avatar' = CONCAT('images/profiles/uploads/',data->'avatar')
Example data:
create table activity (data json);
insert into activity values
('{"avatar":"first.jpg","name":"first name"}'),
('{"avatar":"second.jpg","name":"second name"}'),
('{"avatar":"third.jpg","name":"third name"}');
In Postgres 9.4 you should create an auxiliary function:
create or replace function add_path_to_avatar(json)
returns json language sql as $$
select json_object_agg(key, value)
from (
select
key,
case key::text when 'avatar' then
'images/profiles/uploads/' || value
else value
end
from json_each_text($1)
) s
$$;
update activity
set data = add_path_to_avatar(data)
returning data;
data
-----------------------------------------------------------------------------
{ "avatar" : "images/profiles/uploads/first.jpg", "name" : "first name" }
{ "avatar" : "images/profiles/uploads/second.jpg", "name" : "second name" }
{ "avatar" : "images/profiles/uploads/third.jpg", "name" : "third name" }
(3 rows)
In Postgres 9.5 you can use the function jsonb_set():
update activity
set data = jsonb_set(
data::jsonb,
'{avatar}',
format('"images/profiles/uploads/%s"', data#>>'{avatar}')::jsonb);