OrientDB - TRAVERSE all levels getting only the Vertexes ID - orientdb

When I run this command in OrientDB, I get all the nodes related, according to depth. (I get all depths, it is working)
TRAVERSE * FROM (select from Nodes where node = "817") while $depth<=5
I want only the vertexes ID, not all fields (*), from all levels (depth 5)
I also tried the commands bellow, but I can get only one depth, not all depths (depth 5 or more)
TRAVERSE V.out FROM (select from Nodes where node = "817") while $depth<=5
TRAVERSE outE() FROM (select from Nodes where node = "817") while $depth<=5
TRAVERSE out("related") FROM (select from Nodes where node = "817") while $depth<=5
Please help me.
Thanks.

Try this:
select #rid from (TRAVERSE * FROM (select from Nodes where node = "817") while $depth<=5)
Regards

Related

Postgres SQL - audit check compare

I have a table TEST. I am concerned about two columns - NODE and DESCRIPTION - in that table. There are exactly two records for each DESCRIPTION. The NODE should be the same value for each of these two. I would like to output each record where DESCRIPTION has different NODE.
This is an audit check. In ideal, there is no OUTPUT. But when DESCRIPTION has two different nodes, would like to output.
Thanks
The simplest would be to aggregate by description and node, to count matching rows and to display them if there are not just two
SELECT description, node, count(*)
FROM my_table
GROUP BY description, node
HAVING count(*) <> 2;
The issue is finding different node,description combinations so count() ... group will not solve it as that identifies only the number of rows where they are the same. Try:
select distinct t1.description, t1.node, t2.node
from test t1
join test t2
on (t1.description = t2.description and
t1.node != t2.node)
where t1.node < t2.node
order by description, t1.node;

pgRouting: route starting from closest node along edge

I am trying to find a way to route from the closest point on a linestring to my current location (lat, long). So far I am able to get the shortest path but it starts from the very beginning of the linestring (aka source). I am using prg_trsp
http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html
because it has a feature to specify the starting position along the linestring. I am able to correctly calculate the distance along the linestring and pass the values to the function but cannot figure out how to use the results from the function (pgr_costResult[]) to specify where the route should start (partially along the closest linestring).
I have a feeling I am doing something wrong with the join when I go to join the results from the routing algorithm to my edge table to get the geometry because when I join it uses the edge table's full geometry and not segments. Although, looking at the documentation, I don't see where you get a returned segment from the routing function.
Below is a screenshot of what I am trying to do (red line) and what I have (blue line) the point is the current location. The red line comes from using the pgrouting plugin in qgis with the trsp(edge) selection.
See code below:
Any help would be much appreciated!
SELECT st_linemerge(edgeTable.geom_way) FROM pgr_trsp('SELECT id, source, target, cost FROM edgeTable',
(SELECT id FROM origin),
(SELECT * FROM sourcePos),
(SELECT id FROM destination),
(SELECT * FROM destPos),
false, false) AS shortestPath
JOIN edgeTable ON shortestPath.id2 = edgeTable.id;
origin is the id of the starting route
sourcePos is how far along the linestring to offset
destination is the id of the end linestring
destPos is the fraction of the end linestring
all as specified here: http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html
Its because pgr_trsp() function doesn't give the output your are excepting. Pg_routing Plugin in QGIS does the snapping of the route generated from pgr_trsp(). So you have the output of red line snapped close to your point. So just pgr_trsp() won't give you your desired output. What you are trying to do is a bit complicated but possible. Here is how I solved this problem
WITH
--Make a start point
start_pt as (
select st_setsrid(st_makepoint(204845.95, 2410097.47), 32643) as starting),
--Make a End Point
end_pt as (
select st_setsrid(st_makepoint(204937.15, 2409430.86), 32643) as ending),
--Select Closest source node and its geom for start point
source_code AS (
select source, geom from edgeTable order by st_distance(geom, (select starting from start_pt)) limit 1),
--Select closest target node and its geom for end point
target_code AS (
select target, geom from edgeTable order by st_distance(geom, (select ending from end_pt)) limit 1),
--Route Union from pgr_trsp()
route as (
SELECT ST_LineMerge(ST_union(geom)) as geom, round( CAST(float8 (st_length(ST_union(geom))/1000) as numeric), 2) as length from (
SELECT geom FROM pgr_trsp(
'SELECT feat_id as id, source, target, cost_len as cost, geom FROM edgeTable',
(select source from source_code), (select target from target_code), false, false
) as di JOIN edgeTable
ON di.id2 = edgeTable.id) as foo)
--Finaly snap the route to precisely matach our start and end point
select ST_Line_Substring(geom,
ST_LineLocatePoint(geom, (select starting from start_pt)),
ST_LineLocatePoint(geom, (select ending from end_pt)))
from route
The only issue I have is that I have to switch Starting and Ending Point in last select statement. This can be handled via writing a function. Here is my output
Hope this Help...

Snap points to linestring in Postgis

This code snap line to points. Any ideas how to modify the code to snap the points to line. Thanks.
DROP TABLE IF EXISTS test_gps_point2;
SELECT D.ordinality As sub_id, D.geom::geometry(LINESTRING,3414) AS
geom INTO test_table
FROM
gtd1304_line_2a AS L
LEFT JOIN LATERAL
( -- form a multipoint of all the nodes
-- close enough to line to be considered on the line
SELECT
ST_Union(N.geom ORDER BY L.matched_line <-> N.geom) AS geom
FROM gtd1304_point_2 AS N
WHERE ST_DWithin(L.matched_line, N.geom, 10000)
) AS MP ON TRUE
CROSS JOIN LATERAL
-- snap the LINE to the MP which forces nodes to be injected to the line
-- then split at these node location and dump multilinestring into individual lines
ST_Dump(
COALESCE(ST_Split(ST_Snap(MP.geom, L.matched_line, 10), matched_line), MP.geom)
) WITH ORDINALITY AS D;
As far as I know you cannot do that, at least not with ST_Snap. I think the reason is that since you snap something A onto something B and get back something of type A with B snapped on it, and you can't get back something of type point with something snapped on it since then it becomes a line.

Deleting duplicate edges from edge table

I have thought of following query but it seems syntactically wrong.
delete from table where geom_line in(select distinct(a.geom_line) from table
a ,table b where a.source=b.target and b.source=a.target);
my idea is to delete on of the edges of there exists edges where same source to target is target to source in another edge that is two edges for nodes 1 and 2, from 1->2 and 2->1 and i will delete one of them.
When running only the subquery i get distinct edges with there "geom_lines" as 2000 rows while when i run the whole query 4000 rows are deleted what could be wrong here?
That should be as simple as
DELETE FROM "table" a
USING "table" b
WHERE a.source = b.target
AND a.target = b.source
AND a.source > a.target;

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.