How can I query Edge metadata in Orientdb? - orientdb

I want to know information about an edge named 'own' from metadata, Instead of querying my large graph in which bulk of nodes are present. I want information like all the 'from' and 'to' classes for the edge 'own'.
I have tried this -
select expand(properties) from (
select expand(classes) from metadata:schema
) where name = 'Customers'
where i can know information about nodes with class = Customers. Similarly i want to know information about my edge named 'own'. Thanks.
Answer - After suggestion from Allesandro , I am able to do the above thing using .
create property own.in LINK order
create property own.out LINK customer
select expand(properties) from ( select expand(classes) from metadata:schema ) where name = 'own'
Lets consider that this edge named 'own' is created between 10 classes in a way shown here -
customer -> own -> order -> own -> order_detail -> own -> item -> own -> ..... so on
Now I want to query metadata for edge own by
select expand(properties) from (
select expand(classes) from metadata:schema
) where name = 'Own'
and know that edge is relating all classes in the given sequence.
customer -> order -> order_detail -> item -> ... so on
Thanks.

I don't know if I understand correctly, but you could use
select out.#class, in.#class from own
UPDATE
If you use some constrains on your class "own" like:
create property own.out LINK customer
create property own.in LINK customer
you could use
select expand(properties) from ( select expand(classes) from metadata:schema ) where name = 'own'
Hope it helps.

Related

Updating Group Number based on swap records in postgresql

I just have a two column says like below
Ref Comp
A B
B A
I have the data like this like swapping. Now i just need to provided the same group number for both the records like mentioned below. I our case both the records are same so i need to provide same number for both the records in seperate column. Please provide any solution for this.
GROUP REF COMP
1 A B
1 B A
You can use the Window Function dense_rank ... in the over(...) use just the order clause: (see demo)
select dense_rank() over( order by least(ref,comp), greatest(ref,comp) ) as "Group"
, ref
, comp
from <your_table>
order by "Group", least(ref,comp);
For demo, I added a couple additional data rows. I seldom trust test result set with only 1 basic item. In this case "Group".

How to do recursive lateral join in PostgreSQL?

I have a treelike data structure Object -> package -> package -> .... -> package. I have a query over table containing the Objects and I need to check if the topmost parent has a value set or not.
using only with recursive CTE will just give me all the packages and I don't know which is the topmost parent for my current object. With lateral join i can make a query per row to check for value but I can't seem to find a way to make a query that would work like recursive lateral join.
The output of the query should be a table containing all the values of Object and a value from the topmost package.
Is there a way to do it purely in SQL or do I need to have some intermediate data processing on server side?
It's a bit unclear to me what you are trying to achieve, but:
I need to check if the topmost parent has a value set or not.
This can be done by "carrying" the root information through the recursion. In the root query of the CTE, you can select the attribute you want to make available to every level. In the recursive part you simply take the attribute from the parent.
Something along the lines:
with recursive all_packages as (
select t.*, p.some_column as root_value
from the_table t
where <condition to select the roots>
union all
select t.*, p.root_value
from the_table t
join all_packages p on p.some_id = t.some_parent_id
where p.root_value .... (do something with the root value)
)
select *
from all_packages;

Postgresql query to select records that do not reference another member in the group

How would you structure the following query:
"all records with attribute=true that do not reference another member in the group"
Every record has a "parent_id" that references another record in the same table. I want to select nodes whose "parent_id" does not reference another member in the selected group. Can this be done in postgresql? How would I do it?
At a very generic level, using a subquery something like this should work:
SELECT *
FROM Records
WHERE parent_id NOT IN (
SELECT id
FROM Records
WHERE
attribute=TRUE
)
AND attribute=TRUE
But as #a_horse_with_no_name commented, if that doesn't help then you should edit question to provide more details on what you have, what you expect, and what you have tried.
WITH yt AS (SELECT * FROM your_table WHERE attribute=true)
SELECT t.* FROM yt t WHERE NOT EXISTS (SELECT 1 FROM yt WHERE id = t.reference_id)

Select a single record on basis of Group By "Having"

I have a table say "T1" from which I have to select only one record which has been last updated by any user. The expected result should be somewhat like :-
Since you want the most recent DATETIME for each transaction (based on comments in response to another answer), you actually want to be able to retrieve more than just one record - you want to retrieve one for each group of transactionID:
SELECT transactionID, userID, MAX(updatedDateTime) AS MostRecent
FROM T1
GROUP BY transactionID
This works with test data that includes additional transactionIDs. I'll add a SQLFiddle if the site will work for me . . .
You can try this.
SELECT X.* FROM T1 X
WHERE X.updatedDateTime=(SELECT MAX(updatedDateTime) FROM Temp WHERE temp.userID = T1.userID)

Find cluster given node in PostgreSQL

I am representing a graph in Postgres 9.1 (happens to be bidirectional and cyclic):
CREATE TABLE nodes (
id SERIAL PRIMARY KEY,
name text
);
CREATE TABLE edges (
id SERIAL PRIMARY KEY,
node1_id int REFERENCES nodes(id),
node2_id int REFERENCES nodes(id)
);
Given a particular node ID, want to retrieve all other nodes in that cluster. I started with the "Paths from a single node" example here, and this is where I got:
WITH RECURSIVE search_graph(id, path) AS (
SELECT id, ARRAY[id]
FROM nodes
UNION
SELECT e.node2_id, sg.path || e.node2_id
FROM search_graph sg
JOIN edges e
ON e.node1_id = sg.id
)
-- find all nodes connected to node 3
SELECT DISTINCT id FROM search_graph WHERE path #> ARRAY[3];
I can't figure out a) if there is a simpler way to write this since I don't care about collecting the full path, and b) how to make it traverse in both directions (node1->node2 and node2->node1 for each edge). Shedding any light on a good approach would be appreciated. Thanks!
A couple points.
First, you really want to make sure your path traversal is not going to go into a loop. Secondly handling both sides is not too bad. Finally depending on what you are doing, you may want to push the where clause into the CTE somehow to reduce generating every possible graph network and then picking the one you want.
Traversing itself both directions is not too hard. I haven't tested this but it should be possible with something like:
WITH RECURSIVE search_graph(path, last_node1, last_node2) AS (
SELECT ARRAY[id], id, id
FROM nodes WHERE id = 3 -- start where we want to start!
UNION ALL
SELECT sg.path || e.node2_id || e.node1_id, e.node1_id, e.node2_id
FROM search_graph sg
JOIN edges e
ON (e.node1_id = sg.last_node2 AND NOT path #> array[e.node2_id])
OR (e.node2_id = sg.last_node1 AND NOT path #> array[e.node1_id])
)
-- Moved where clause to start of graph search
SELECT distinct unnest(path) FROM search_graph; -- duplicates possible
Hope this helps.