Couchbase iterate on properties and get value - couchbase

I have a couchbase document like :
{
"data": {
"author1": {
"title": [
"1",
"2"
]
},
"author2": {
"title": [
"3",
"4"
]
}
}
}
And I would like to get with a N1QL request :
1
2
3
4
How is it possible ?

This might work. It assumes that title contains the values you want.
select VALUE ARRAY_FLATTEN(OBJECT_VALUES(OBJECT_UNWRAP(b))[*].title,1)
from books b
OBJECT_UNWRAP gets rid of the data and unwraps to peel away a layer.
OBJECT_VALUES then returns the values of the individual fields (whatever they are: author1, authorA, author-123)
The [*].title syntax returns every title field in the resulting array
ARRAY_FLATTEN combines the arrays
Finally, use VALUE to get the raw values.
I am NOT claiming this is the best approach, but it seems to work okay with the small sample data set (of 2 docs) that I created based on your question.

SELECT ARRAY_FLATTEN(ARRAY v.title FOR n:v IN b.data END,1) AS title
FROM books b;
OR
SELECT ARRAY_FLATTEN(OBJECT_VALUES(b.data)[*].title,1) AS title
FROM books b;
If need across the documents
WITH books AS ([ { "data": { "author1": { "title": [ "1", "2" ] }, "author2": { "title": [ "3", "4" ] } } },
{ "data": { "author1": { "title": [ "1", "5" ] }, "author2": { "title": [ "6", "1" ] } } }
])
SELECT DISTINCT RAW t
FROM books AS b
UNNEST ARRAY_FLATTEN(ARRAY v.title FOR n:v IN b.data END,1) AS t;
FOR n:v IN b.data
Looping construct
If b.data is OBJECT n holds field name, v holds value
If b.data is ARRAY n holds position, v holds value

Related

MySQL How to join 2 tables and get a combined response

I have 2 tables projects and images. My goal is to get all images of a project and get this kind of response.
{
"data": {
"id": "this is project id",
"title": "project title",
...
"images": [
{
"image": "images/image-name.jpg",
},
{
"image": "images/image-name.jpg",
}
]
}
}
But what I get is this
{
"data": [
{
"image": "image-path.jpg"
},
{
"image": "image-path.jpg"
}
]
}
My table structure look like this
projects
id
title
description
collaboration
role
case_study
slug
direction
uuid
text
text
text
text
text
text
enum(ltr, rtl)
images
id
images
project_id
uuid
image_path
uuid
My current query looks like this
`SELECT images.image FROM images JOIN projects ON images.project_id = ${id}`
You can try this to combine your queries from two tables to one json:
SELECT json_object(
'id',p.id,
'title',p.title,
'images',( select json_arrayagg(json_object('image',i.`image`)) from images i where i.project_id = 1 )
) as json
FROM projects p WHERE p.id = 1;
You will get this:
{
"id": 1,
"title": "gx",
"images": [
{
"image": "foo"
},
{
"image": "bar"
}
]
}
But finally i have to say that combine your query result in your code is the better way.

Filter a list with multiple conditions using WITH in Cypher,Neo4j

I'm new to Neo4j. I'm kind of got stuck for loading a JSON file into Neo4j database.
I have a list of tags for many transactions. Each transaction tag can have one or two tags: third-party and category.
Here is an example JSON.
{
"tags": [
[
{
"thirdParty": "Supermarkets"
},
{
"category": "Groceries"
}
],
[
{
"category": "Rent"
}
],
[
{
"thirdParty": "Education"
},
{
"category": "Education"
}
]
.....
]
}
I only want to find objects that have both category and thirdParty(some objects only have one tag).
And here is my code, the list is just a list of categories I want.
CALL apoc.load.json("file:///full.json")
YIELD value
with ['Gambling','Subscription TV','Telecommunications'] as list
UNWIND value.tags as tags
WITH [tag in tags where tag.category IN list AND tag.thirdParty IS NOT NULL] AS temp
RETURN temp
The weird thing is this always return me a list null. But with only one condition then it will work, like only find objects in the list or only thirdParty is not null.
But combine the 2 conditions together, it will always return a list of null.
Does anyone know how to fix this?
Thanks
Your UNWIND seems to return a list of maps, not a map. But the good thing is that with apoc, you can convert it easily.
this works:
WITH [
[
{
thirdParty: "Supermarkets"
},
{
category: "Groceries"
}
],
[
{
category: "Rent"
}
],
[
{
thirdParty: "Education"
},
{
category: "Education"
}
]
]
AS tagsList
WITH tagsList, ['Groceries','Subscription TV','Telecommunications'] as list
UNWIND tagsList as tags
WITH list,
apoc.map.fromPairs(
REDUCE(arr=[],tag IN tags |
arr+[[keys(tag)[0],tag[keys(tag)[0]]]]
)
) AS tagMap
WHERE tagMap.category IN list AND tagMap.thirdParty IS NOT NULL
RETURN tagMap
returns
{
"thirdParty": "Supermarkets",
"category": "Groceries"
}

Couchbase N1QL - Nest array using keys

i'm new to Couchbase and N1QL syntax and i'm facing an issue.
Let's say we have 3 type of documents:
Doc1 of TypeA with key = typeA:Doc1
{
"type": "typeA"
"id": "Doc1",
"sequences": [
"typeB:Doc2"
]
}
Doc2 of TypeB with key = typeB:Doc2
{
"id": "Doc2",
"processors": [
{
"order": 1,
"id": "typeC:Doc3"
}
]
}
Doc3 of TypeC with key = typeC:Doc3
{
"id": "Doc3",
"prop": "value"
}
What i want to achieve is to nest these 3 objects by their document keys in ordere to have a unique document with this structure:
{
"id": "Doc1",
"sequences": [
{
"id": "Doc2",
"processors": [
{
"order": 1,
"id": "Doc3",
"prop": "value"
}
]
}
]
What i've done is to nest the first two documents to obtain a partial result. But i'm tryng to integrate also the third document.
Here's my attempt:
SELECT dev.*,
ARRAY sq_i FOR sq_i IN prseq END AS sequences
FROM data dev
NEST data prseq ON KEYS dev.sequences
WHERE dev.type = 'TypeA'
Can anyone help me with the third level of nesting?
Thank you.
Use subqueries
SELECT dt.*,
(SELECT ds.*,
(ARRAY OBJECT_ADD((SELECT RAW dp FROM data AS dp USE KEYS v.id)[0], "order", v.`order`)
FOR v IN ds.processors
END) AS processors
FROM data AS ds USE KEYS dt.sequences) AS sequences
FROM data AS dt
WHERE dt.type = 'TypeA';

get tag with json ot jsonb query

I am using PostgreSQL 11.
I'm trying get "wmnote" tag from this json(this is a fragment, it is necessary to close the labels):
{
"order": [
{
"notes": {
"note": []
},
"onHold": "false",
"wmnotes": {
"wmnote": []
},
"invoices": {
"invoiceDetail": []
},
"confirmed": "true",
"enteredBy": "",
"entryType": "",
"orderType": "DTC",
"orderEvent": "Update",
"orderLines": {
"orderLine": [
{
"notes": {
"note": []
},
"isGift": "false",
"itemID": "4027956",
"onHold": "false",
"wmnotes": {
"wmnote": [
{
"noteSeq": "1",
"noteCode": "",
"noteType": "DDate",
"visibility": "0",
"commentText": "02/07/2019"
}
This is my query:
select o.info->>'order'-> 'orderLines'->'wmnotes'->'wmnote'
from customer_orders o
where o.order_id = 1;
But result is null.
The column name info is a data type jsonb.
They could help me with the construction of the query!!
Three points:
->> gives out a text not a type JSON. So you would not be able to work with the result as a JSON object. Use -> instead as you did with all furth steps
order contains an array. So you have to specify which array element you are searching for. If you want to search the first element you need to call "order" -> 0 -> "orderlines" (note JSON arrays are zero based!)
orderline contains an array as well. See point 2.
So your query should look like:
SELECT o.info->'order'->0 -> 'orderLines' -> 'orderLine' -> 0 -> 'wmnotes'->'wmnote'
FROM customer_orders o
demo: db<>fiddle

Can't parsing an array of objects with Dynamic Keys using OPENJSON And SQL Server 2017

I'm after running into some trouble parsing a set of JSON documents using SQL Server 2017.
I've encountered a nested array (sample below) within a document which uses dynamic ObjectId's i.e. 123 as the object Key as opposed to using a static key i.e. Category and then having a separate key:value to ref the ObjectId.
As a result I can't extract the items to a table using the regular CROSS APPLY OPENJSON syntax without specifying each individual Object Id (there are thousands)?
Is there a way to do this without referencing each ObjectId explicitly ideally i'd like to return all product items in a table and just have a field withe the categoryId.
"ProductItems": {
"123": [
{
"item": "13663"
}
]
"124": [
{
"value": "2336"
},
{
"value": "3667"
}
],
"453": [
{
"value": "8667"
},
{
"value": "1956"
}
]
}
Try something like this:
DECLARE #x NVARCHAR(MAX)=
'{"ProductItems":{
"123": [
{
"item": "13663"
}
],
"124": [
{
"value": "2336"
},
{
"value": "3667"
}
],
"453": [
{
"value": "8667"
},
{
"value": "1956"
}
]
}}'
SELECT j2.*, j3.* FROM OPENJSON(#x) j1
CROSS APPLY OPENJSON(j1.Value) j2
CROSS APPLY OPENJSON(j2.Value) j3