Edge pointing to an edge? - orientdb

In OrientDB 3.0.x (x>5) is it possible to have an edge, one of end of which is also an edge? It seems possible, but not explained in the docs:
--Define vertex A,B,C
create class testVertexA extends V;
create class testVertexB extends V;
create class testVertexC extends V;
--Define EdgeA that connects 2 vertexes -A and B
create class testEdgeA extends E;
create property testEdgeA.in link testVertexA;
create property testEdgeA.out link testVertexB;
--Define EdgeB that connects EdgeA and vertex C - is this possible?
create class testEdgeB extends E;
create property testEdgeB.in link testVertexC;
create property testEdgeB.out link testEdgeA;
Next, we put in some data, to see if this works at all:
orientdb > insert into testVertexA;
Inserted record '[testVertexA#225:0 v1]' in 0.000000 sec(s).
orientdb > insert into testVertexB;
Inserted record '[testVertexB#233:0 v1]' in 0.016000 sec(s).
orientdb > insert into testVertexC;
Inserted record '[testVertexC#241:0 v1]' in 0.000000 sec(s).
orientdb > insert into testEdgeA set in=#225:0, out=#233:0;
Inserted record '[testEdgeA#249:0{in:#225:0,out:#233:0} v1]' in 0.000000 sec(s).
orientdb > insert into testEdgeB set in=#241:0, out=#249:0;
Inserted record '[testEdgeB#257:0{in:#241:0,out:#249:0} v1]' in 0.000000 sec(s).
orientdb > select from testEdgeB;
+----+------+---------+------+------+
|# |#RID |#CLASS |in |out |
+----+------+---------+------+------+
|0 |#257:0|testEdgeB|#241:0|#249:0|
+----+------+---------+------+------+
1 item(s) found. Query executed in 0.0 sec(s).
orientdb > select from #241:0
+----+------+-----------+
|# |#RID |#CLASS |
+----+------+-----------+
|0 |#241:0|testVertexC|
+----+------+-----------+
1 item(s) found. Query executed in 0.0 sec(s).
orientdb > select from #249:0
+----+------+---------+------+------+
|# |#RID |#CLASS |in |out |
+----+------+---------+------+------+
|0 |#249:0|testEdgeA|#225:0|#233:0|
+----+------+---------+------+------+
1 item(s) found. Query executed in 0.0 sec(s).
Can someone affirm this . Thanks

Related

Record version after conflict

I use Orientdb 2.2.35. I insert some documents into it until a conflict occurs.
When I check the record version, it didn't change during the insertion (After conflict). In my example you can see the version of #18:0 after I insert an edge (create edge mye from #18:0 to #19:0)
Error:
com.orientechnologies.orient.core.exception.OConcurrentModificationException:
Cannot UPDATE the record #18:0 because the version is not the latest.
Probably you are updating an old record or it has been modified by
another user (db=v2 your=v1)
orientdb {db=TestDB}> select * from #18:0
+----+-----+------+----+------------------------------------------------------------------------+
|# |#RID |#CLASS|id |out_MyE |
+----+-----+------+----+------------------------------------------------------------------------+
|0 |#18:0|MyV |1 |[#22:0,#22:1,#22:2,#22:3,#22:4,#22:5,#22:6,#22:7,#22:8,#22:9(size=5000)]|
+----+-----+------+----+------------------------------------------------------------------------+
1 item(s) found. Query executed in 0.002 sec(s).
orientdb {db=TestDB}> load record #18:0
DOCUMENT #class:MyV #rid:#18:0 #version:2
+----+-------+------------------------------------------------------------------------+
|# |NAME |VALUE |
+----+-------+------------------------------------------------------------------------+
|0 |id |1 |
|1 |out_MyE|[#22:0,#22:1,#22:2,#22:3,#22:4,#22:5,#22:6,#22:7,#22:8,#22:9(size=5000)]|
+----+-------+------------------------------------------------------------------------+
OK
orientdb {db=TestDB}> create edge mye from #18:0 to #19:0
+----+--------+------+-----+-----+
|# |#RID |#CLASS|out |in |
+----+--------+------+-----+-----+
|0 |#22:5250|MyE |#18:0|#19:0|
+----+--------+------+-----+-----+
Created '1' edges in 0.017000 sec(s).
orientdb {db=TestDB}> select * from #18:0
+----+-----+------+----+------------------------------------------------------------------------+
|# |#RID |#CLASS|id |out_MyE |
+----+-----+------+----+------------------------------------------------------------------------+
|0 |#18:0|MyV |1 |[#22:0,#22:1,#22:2,#22:3,#22:4,#22:5,#22:6,#22:7,#22:8,#22:9(size=5001)]|
+----+-----+------+----+------------------------------------------------------------------------+
1 item(s) found. Query executed in 0.001 sec(s).
orientdb {db=TestDB}> load record #18:0
DOCUMENT #class:MyV #rid:#18:0 #version:2
+----+-------+------------------------------------------------------------------------+
|# |NAME |VALUE |
+----+-------+------------------------------------------------------------------------+
|0 |id |1 |
|1 |out_MyE|[#22:0,#22:1,#22:2,#22:3,#22:4,#22:5,#22:6,#22:7,#22:8,#22:9(size=5001)]|
+----+-------+------------------------------------------------------------------------+
OK
This is a common issue caused by a wrong approach to concurrency or transactions.
You're gonna need to troubleshoot the cause and either write fail-safe code or change your graph consistency level
OrientDB | Troubleshooting OConcurrentModificationException

Using Traverse from to project the records in OrientDB

I'm using the Vehicle History database with OrientDb Studio 2.2.8, and I want to project all of the records of the automobile class that are made by Kia.
The schema for the database looks like this:
(Automobile) --isModel--> (Model) --isMake--> (Make)
where Automobile, Model, and Make are vertices and isModel, and isMake are edge types.
I want to use a traverse statement to return an equivalent result set as I get from this command:
Select expand(in('isMake').in('isModel')) from Make where name = "Kia"
whose result is...
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|# |#RID |#CLASS |color |convertib|out_isMod|trailerHi|emissions|safety |out_Purch|VIN |
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|0 |#17:1441|Automo...|White |true |[#24:1...|false |2016-0...|2014-0...|[#23:5...|840CDC...|
|1 |#17:1576|Automo...|Maroon |true |[#24:1...|false |2010-0...|2004-0...|[#23:5...|E71761...|
|2 |#17:1503|Automo...|Dark Gray|true |[#24:1...|false |2009-0...|2016-1...|[#23:5...|FAEB6F...|
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
I tried running this:
Select
from (traverse in from Make while $depth <= 2)
where name = "Kia"
I just get one record returned, and it's not of the Automobile class like I expected it to be. It is from Make.
+----+-------+------+----+-------------------------------------+----------------------------+
|# |#RID |#CLASS|name|in_isMake |out_Sold |
+----+-------+------+----+-------------------------------------+----------------------------+
|0 |#15:612|Make |Kia |[#25:1767,#25:2036,#25:2067,#25:2131]|[#22:5153,#22:5383,#22:5655]|
+----+-------+------+----+-------------------------------------+----------------------------+
Basically, I want to use a Traverse starting from Make to project the three Kia automobiles in the database.
Can you try this?
SELECT FROM (TRAVERSE in()
FROM (SELECT FROM Make where name='Kia'))
WHERE #class='Automobile'

Orientdb : Traversal not producing correct output

Can anybody tell me how to get all nodes and edges in a traversal?
For example, if I run the following query:
select from (TRAVERSE in(), inE() FROM (SELECT FROM Example_Class WHERE #rid = #13:187))
the result changes every time.
Requirement: Get all unordered nodes and edges from a specific node (#13:187 in the example above).
One way to retrieve the edges and nodes encountered while traversing a graph from a particular node, say NODE, is using the query:
> traverse outE(), inV() from NODE
Here is an example. First, let's just run out() to retrieve the encountered nodes (here the start (#11:11) and end (#11:15)); the resultant rows give the edge information:
> traverse out() from #11:11
----+------+------+-----+-------+-------
# |#RID |#CLASS|label|in_E3 |out_E3
----+------+------+-----+-------+-------
0 |#11:11|Circle|4 |[#15:2]|[#15:4]
1 |#11:15|Circle|8 |[#15:4]|null
----+------+------+-----+-------+-------
Here the picture is: (#11:11) -[#15:4]> (#11:15)
Now let's formulate the query so that the rows of the result-set include both nodes and edges:
> traverse outE(), inV() from #11:11
----+------+------+-----+-------+-------+------+------
# |#RID |#CLASS|label|in_E3 |out_E3 |in |out
----+------+------+-----+-------+-------+------+------
0 |#11:11|Circle|4 |[#15:2]|[#15:4]|null |null
1 |#15:4 |E3 |4>8 |null |null |#11:15|#11:11
2 |#11:15|Circle|8 |[#15:4]|null |null |null
----+------+------+-----+-------+-------+------+------

DB2 SQL to aggregate value for months with no gaps

I have 2 tables which I need to join against, along with a table that is generated inline using WITH. The WITH is a daterange, and I need to display all rows from 1 table for all months, even where no data exists in the 2nd table.
This is the data within the tables :
Table REFERRAL_GROUPINGS
referral_group
--------------
VER
FRD
FCC
Table DATA_VALUES
referral_group | task_date | task_id | over_threshold
---------------+------------+---------+---------------
VER | 2015-10-01 | 10 | 0
FRD | 2015-11-04 | 20 | 1
The date range will need to select 3 months :
Oct-2015
Nov-2015
Dec-2015
The data I expect to end up with will be :
MonthYear | referral_group | count_of_group | total_over_threshold
----------+----------------+----------------+---------------------
Oct-2015 | VER | 1 | 0
Oct-2015 | FRD | 0 | 0
Oct-2015 | FCC | 0 | 0
Nov-2015 | VER | 0 | 0
Nov-2015 | FRD | 1 | 1
Nov-2015 | FCC | 0 | 0
Dec-2015 | VER | 0 | 0
Dec-2015 | FRD | 0 | 0
Dec-2015 | FCC | 0 | 0
DDL to create the 2 tables and populate with data is as below..
CREATE TABLE test_data (
referral_group char(3),
task_date date,
task_id integer,
over_threshold integer);
insert into test_data values
('VER','2015-10-01',10,1),
('FRD','2015-11-04',20,0);
CREATE TABLE referral_grouper (
referral_group char(3));
insert into referral_grouper values
('FRD'),
('VER'),
('FCC');
This is a very cut-down example which uses the minimal tables/columns for this example, which is why I have no primary keys/indexes.
I can get this running under LUW no problem, by using NOT EXISTS in the joins as per this SQL.
WITH DATERANGE(FROM_DTE,yyyymm, TO_DTE) AS
(
SELECT DATE('2015-10-01'), YEAR('2015-10-01')*100+MONTH('2015-10-01'), '2015-12-31'
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT FROM_DTE + 1 DAY, YEAR(FROM_DTE+1 DAY)*100+MONTH(FROM_DTE+1 DAY), TO_DTE
FROM DATERANGE
WHERE FROM_DTE < TO_DTE
)
select
referral_grouper.referral_group,
daterange.yyyymm,
count(test_data.task_id) AS total_count,
COALESCE(SUM(over_threshold),0) AS total_over_threshold
FROM
test_data
RIGHT OUTER JOIN daterange ON (daterange.from_dte=test_data.task_date OR NOT EXISTS (SELECT 1 FROM daterange d2 WHERE d2.from_dte=test_data.task_date))
RIGHT OUTER JOIN referral_grouper ON (referral_grouper.referral_group=test_data.referral_group OR NOT EXISTS (SELECT 1 FROM referral_grouper g2 WHERE g2.referral_group=test_data.referral_group))
GROUP BY
referral_grouper.referral_group,
daterange.yyyymm
However... This needs to work on ZOS, and under ZOS you cannot use subqueries with EXISTS in a join. Removing the NOT EXISTS means the non existing rows no longer show up.
There must be a way to write the SQL to return all rows from the 2 linking tables without using NOT EXISTS, but I just cannot seem to find it. Any help with this would be very appreciated as it has me stumped

OrientDB - Update with SUBSELECT

I want to update some rows of my table basing on other rows of the same table:
I try this:
UPDATE MyTable set myField =
(SELECT T1.myField
FROM MyTable T1
WHERE T1.id.substring(start,stop) = MyTable.id.substring(start,stop))
But OrientDB throws an error like this:
com.orientechnologies.orient.core.sql.OCommandSQLParsingException: Error on parsing command at position #XXX: Invalid keyword 'T1' Command:
first of all you in OrientDB you can't use Alias on Classes.
In this case you could use $parent.$current in a subquery, something like:
> update MyTable set myField = (
> select myField
> from MyTable
> where myField is null
> and id.substring(8,13) = $parent.$current.id.substring(8,13) and something else...
> ) where myField is null and something else...
Be careful to the length of the id...
Best Regards
M.
This is not a string update, but an integer update in place. Using the provided GratefulDeadDatabase, you can do:
CONNECT remote:localhost/GratefulDeadConcerts;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |5
2 |null |1
3 |null |531
4 |null |394
----+------+------------
UPDATE v SET performances = eval('performances + 2') WHERE performances IS NOT NULL;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |7
2 |null |3
3 |null |533
4 |null |396
----+------+------------
So the update works on the data in place. I'm fairly new to OrientDB so maybe an expert can tell me if I just did something horribly horribly wrong.
UPDATE
Notice that in your example you are updating the table with values from the same table. That is, from MyTable into MyTable (unless I misunderstood your query) and even within the same row. You can use criteria on the WHERE clause to only update rows of interest. In my example, that was
WHERE performances IS NOT NULL