how to gather several fields from linked data in one query? - orientdb

I have a graph db with Members and Pages, some members can be ExpertOf some pages. I am trying to build a query giving experts of a given page, with all the pages they are experts of.
To sum up, I have a simple db : Member---(ExpertOf)--->Page
My (quite) working query is
SELECT #rid,title,out('ExpertOf') AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
It works as expected, returning :
{
"result": [
{
"#type": "d",
"#rid": "#-2:0",
"#version": 0,
"rid": "#17:0",
"title": "John Doe",
"expertises": [
"#16:299",
"#16:221",
"#15:160",
"#16:94",
"#16:714"
],
"#fieldTypes": "rid=x,expertises=z"
}
],
"notification": "Query executed in 0.057 sec. Returned 1 record(s)"
}
(btw, I wonder what is this #rid:#-2:0...)
But now, instead of having pages #rid, I would like to have both #rid and title...
I've tried :
SELECT #rid,title,out('ExpertOf').title AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
or (same result)
SELECT #rid,title,out('ExpertOf').include('title') AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
which gives :
"expertises": [
"Wave on string",
"USE A SLOPE",
"Spin coating",
"Gas hydrate",
"Mpemba effect"
],
then
SELECT #rid,title, out('ExpertOf').include('#rid','title') AS
expertises FROM (SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
which returns :
"expertises": [
"#16:299",
"#16:221",
"#15:160",
"#16:94",
"#16:714"
],
whereas I would have hoped
"expertises": [
{ "#rid":"#16:299", "title":"Wave on string" },
{ "#rid":"#16:221", "title":"USE A SLOPE" },
{ "#rid":"#15:160", "title":"Spin coating" },
{ "#rid":"#16:94", "title":"Gas hydrate" },
{ "#rid":"#16:714", "title":"Mpemba effect" }
],
I've tried expand(out('ExpertOf').include('#rid','title')) or unwind expertises, or unionAll(out('ExpertOf').#rid,out('ExpertOf').title) as explained elsewhere, and so on... but no query has given the hoped result.
Is there a way to get this kind of result ? (I've succeded to make it work with a function calling a query on Page, but I am wondering if this can be done in one query, and if my solution is efficient).
Thanks

If you are using HTTP and you want to obtain a nested JSON, you can use fetchplans:
SELECT #rid,title,out('ExpertOf') AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
fetchplan *:0 expertises.rid:1 expertises.title:1 expertises:-2

instead of this,
SELECT #rid,title,out('ExpertOf').include('title') AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)
try to do this one
SELECT #rid,title,out('ExpertOf')['title'] AS expertises FROM
(SELECT expand(in('ExpertOf')) FROM Page WHERE #rid=16:299)

Related

How to improve this query using array or json constructor?

how are you?
I am wondering how to improve this query to return something better to work with. Let me show the tables, the current query and my idea first:
Tables
users
nfts
here owner_id is a fk to users.id
users_nfts (here I save all the creators of the nft, one nft could have more than one creator. This is to calculate royalties later)
Current query and explanation
To be able to code a "buy" nft process (in nodejs) I want to retrieve some data about the nft to buy:
Its price
Its current owner
The creators (to calculate the royalties and update their balances)
SELECT nfts.id, price, owner_id, owner.balance as owner_balance, creators.user_id, users.balance
FROM nfts
INNER JOIN users_nfts as creators
ON nfts.id = creators.nft_id
INNER JOIN users
ON creators.user_id = users.id
INNER JOIN users as owner
ON nfts.owner_id = owner.id
WHERE nfts.id = ${nft_id}
The query works but it's horrible because it retrieves me repeated data (this is what I want to solve). The red square means the repeated data.
What I would like to achieve
I would like to make a query so all the data about the NFT comes in one row. To do that, I need to retrieve the user_id and balance inside an array of tuples or in a json.
The result in my backend could be something like (any ideas here are welcome):
{
"id": "ea850c65-818e-40bd-bb06-af69eaeda4a6", // nft id
"price": 42,
"owner_id": "1134e9e0-02ae-4567-9adf-220ead36a6ef",
"owner_balance": 100,
"creators": [
{
"user_id": "1134e9e0-02ae-4567-9adf-220ead36a6ef",
"balance": 100,
},
{
"user_id": "2134e9e0-02ae-4567-9adf-220ead36a6ea",
"balance": 35,
},
],
},
Thanks in advance for any tips :)
I achieved what I want with this query, using json_agg and json_build_object
SELECT nfts.id, price, owner_id, owner.balance as owner_balance, json_agg(json_build_object('user_id', creators.user_id, 'balance', users.balance)) as creators
FROM nfts
INNER JOIN users_nfts as creators
ON nfts.id = creators.nft_id
INNER JOIN users
ON creators.user_id = users.id
INNER JOIN users as owner
ON nfts.owner_id = owner.id
WHERE nfts.id = ${nft_id}
GROUP BY nfts.id, owner.id;
The query produces the following output:
{
"rows": [
{
"id": "d87716ec-4005-4ccb-9970-6769adec3aa1",
"price": 42,
"owner_id": "7dd619dd-b997-4351-9541-4d8989c58667",
"owner_balance": 58,
"creators": [
{
"user_id": "1134e9e0-02ae-4567-9adf-220ead36a6ef",
"balance": 137.8
},
{
"user_id": "492851bb-dead-4c9d-b9f6-271dcf07a8bb",
"balance": 104.2
}
]
}
]
}
Hope someone else can find this useful.

Creating an AND query on a list of items in Azure Cosmos

I'm building an application in Azure Cosmos and I'm having trouble creating a query. Using the dataset below, I want to create a query that only finds CharacterId "Susan" by searching for all characters that have the TraitId of "Athletic" and "Slim".
Here is my JSON data set
{
"characterId": "Bob",
"traits": [
{
"traitId": "Athletic",
"traitId": "Overweight"
}
],
},
{
"characterId": "Susan",
"traits": [
{
"traitId": "Athletic",
"traitId": "Slim"
}
],
},
{
"characterId": "Jerry",
"traits": [
{
"traitId": "Slim",
"traitId": "Strong"
}
],
}
]
The closest I've come is this query but it acts as an OR statement and what I want is an AND statement.
SELECT * FROM Characters f WHERE f.traits IN ("Athletic", "Slim")
Any help is greatly appreciated.
EDITED: I figured out the answer to this question. If anyone is interested this query gives the results I was looking for:
SELECT * FROM Characters f
WHERE EXISTS (SELECT VALUE t FROM t IN f.traits WHERE t.traitId = 'Athletic')
AND EXISTS (SELECT VALUE t FROM t IN f.traits WHERE t.traitId = 'Slim')
The answer that worked for me is to use EXISTS statements with SELECT statements that searched the traits list. In my program I can use StringBuilder to create a SQL statement that concatenates an AND EXISTS statement for each of the traits I want to find:
SELECT * FROM Characters f
WHERE EXISTS (SELECT VALUE t FROM t IN f.traits WHERE t.traitId = 'Athletic')
AND EXISTS (SELECT VALUE t FROM t IN f.traits WHERE t.traitId = 'Slim')

How do I know if a Facebook Status/Photo/Link is Private?

When I'm getting a status/link/photo from facebook API, how do I know if it has been shared with the public or if it's a private post?
Also - is there a way to query only public posts?
I'm currently using the /<username>/status /<username>/links /<username>/photos endpoints.
With the graph api
From the 3 endpoints you are using, only one gives you access to the privacy settings the /<username>/links. It returns a privacy object, something like this:
{
"id": "USER_FB_ID",
"links": {
"data": [
{
"id": "ID_OF_THE_POST",
"from": {
"name": "Fábio Antunes",
"id": "USER_FB_ID"
},
"message": "Check this awesome link",
"privacy": {
"description": "Friends; Except: Restricted",
"value": "ALL_FRIENDS",
"allow": "",
"deny": "",
"networks": "",
"friends": ""
},
(etc....)
With FQL
To solve your problem you could use FQL this way you can get the 3 endpoints that have public access.
For the links you can use this query:
Select link_id,owner_comment, title, url, privacy FROM link WHERE owner = me() AND privacy.value='EVERYONE'
note: check the link table to see if there are any fields that you may want to add to this query
Since the links table from the 3 endpoints is the only with privacy settings structure to get the user photos and statuses that are public you will have to use the privacy table.
To get all the users public photos I made 2 joins, first I'm getting the user photos, then I want the privacy settings of the photos that are available to everyone and then I select the photos that have the privacy settings public:
SELECT caption,src_big FROM photo WHERE object_id IN (SELECT id FROM privacy WHERE value='EVERYONE' AND object_id IN (SELECT object_id FROM photo WHERE owner=me()))
note: check the photo table to see if there are any fields that you may want to add to this query
To get the public statuses it's the same process for the photos, two joins:
SELECT status_id , message, place_id FROM status WHERE status_id IN (SELECT id FROM privacy WHERE value='EVERYONE' AND object_id IN (SELECT status_id FROM status WHERE uid=me()))
note: check the status table to see if there are any fields that you may want to add to this query

Getting images from facebook group album

I'm having a problem with the Graph API / FQL and I have searched however no solution has come up.
I'm unable to retrieve photos from a group album.
I can retrieve a lot of information regarding that group album which indicates that a group album is just a regular album:
SELECT description, owner, photo_count, type, like_info,
cover_pid, comment_info FROM album WHERE object_id = '1382173765340875'
{
"data": [
{
"description": "10 Desafio Outros!!!",
"owner": 1455136613,
"photo_count": 8,
"type": "normal",
"like_info": {
"can_like": true,
"like_count": 1,
"user_likes": true
},
"cover_pid": "6249764165120950711",
"comment_info": {
"can_comment": true,
"comment_count": 0,
"comment_order": "chronological"
}
}
]
}
Calling "/1382086785349573" gives me the group information.
Calling "/1382086785349573/albums" gives me a list of all the albums in the group including ID, album name and even correct count.
but "albumid/photos" where album ID was retrieved from previous call returns an empty array
Also "/groupid/photos" returns an empty data[] array.
Can anyone tell me why this happens? I already removed my app from sandbox mode but still showing the same problem.
I don't understand why it can retrieve album information including items count and etc but not the photos in it.
Thanks in advance for any help.

FQL query doesn't return the correct results

I'm running the following fql query in the graph explorer:
select album_object_id, object_id, aid, pid from photo where object_id=576544082370719
and i get the correct results i want:
{
"data": [
{
"album_object_id": 520085011349960,
"object_id": 576544082370719,
"aid": "396713620353767_120902",
"pid": "396713620353767_2121634"
}
]
}
however, when adding album_object_id to the statement, nothing is returned:
select album_object_id, object_id, aid, pid from photo where object_id=576544082370719 and album_object_id=520085011349960
{
"data": [
]
}
anyone has any idea?
I tried to report it but they said they can't reproduce
https://developers.facebook.com/bugs/448684285215430
here is another example which doesnt work but it supposed to, what is going on?
select object_id, modified from photo where object_id=507652032628572
this gives the correct result, however:
select object_id, modified from photo where album_object_id=468672926526483 and modified>1365522434
no results on this one.
found out that when adding order by modified desc to the statement, results are fine, thats some kind of work around but well, at least works.