Gephi Plugin/Query Duplicate Edge ID

133 views
Skip to first unread message

Brian O'Keefe

unread,
Oct 4, 2013, 11:21:58 AM10/4/13
to orient-...@googlegroups.com
Hi all,

I'm not sure if I am doing this incorrectly, or if something is wrong with the Gephi plugin functionality, so I outline the steps to reproduce below:

Assuming a local database exists called "Testing":

1.  I create the schema
CREATE CLASS Person extends V;
CREATE CLASS IsParentOf extends E;
CREATE PROPERTY Person.name STRING;

2. I add the vertices
CREATE VERTEX Person SET name = 'Maternal Grandfather'
CREATE VERTEX Person SET name = 'Maternal Grandmother'
CREATE VERTEX Person SET name = 'Paternal Grandfather'
CREATE VERTEX Person SET name = 'Paternal Grandmother'
CREATE VERTEX Person SET name = 'Mom'
CREATE VERTEX Person SET name = 'Dad'
CREATE VERTEX Person SET name = 'Me'
CREATE VERTEX Person SET name = 'Junior'
CREATE VERTEX Person SET name = 'Neighbor'

3. I add the edges
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Maternal Grandfather') TO (SELECT FROM Person where name = 'Mom')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Maternal Grandmother') TO (SELECT FROM Person where name = 'Mom')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Paternal Grandfather') TO (SELECT FROM Person where name = 'Dad')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Paternal Grandmother') TO (SELECT FROM Person where name = 'Dad')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Mom') TO (SELECT FROM Person where name = 'Me')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Dad') TO (SELECT FROM Person where name = 'Me')
CREATE EDGE IsParentOf FROM (SELECT FROM Person where name = 'Me') TO (SELECT FROM Person where name = 'Junior')

My goal is to get the part of the graph dealing with "Me and my family" (e.g., exclude "Neighbor")
The query SELECT * FROM (TRAVERSE any() FROM (SELECT FROM V WHERE name='Me')) achieves this, so the url I query is:

The result is:
{"an":{"#11:2":{"name":"Paternal Grandfather"}}}
{"an":{"#11:1":{"name":"Maternal Grandmother"}}}
{"an":{"#11:0":{"name":"Maternal Grandfather"}}}
{"an":{"#11:7":{"name":"Junior"}}}
{"an":{"#11:6":{"name":"Me"}}}
{"an":{"#11:5":{"name":"Dad"}}}
{"an":{"#11:4":{"name":"Mom"}}}
{"an":{"#11:3":{"name":"Paternal Grandmother"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:5","target":"#11:3"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:6","target":"#11:5"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:6","target":"#11:4"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:7","target":"#11:6"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:4","target":"#11:0"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:4","target":"#11:1"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:5","target":"#11:2"}}}

The issue is that Gephi will only add the first edge, and then reports that "Edge added event ignored for edge #-1:-1: Edge already exists".

Is this a bug, or is there a better way to achieve my goals with a different query?

Thanks,

Brian

Luca Garulli

unread,
Oct 5, 2013, 4:12:37 PM10/5/13
to orient-database
Hi Brian,
you could use the TRAVERSE command instead of Traverse() function:

SELECT expand( both("IsParentOf") ) FROM V WHERE name='Me'

Lvc@



Lvc@


--
 
---
You received this message because you are subscribed to the Google Groups "OrientDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to orient-databa...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Brian O'Keefe

unread,
Oct 7, 2013, 8:16:53 AM10/7/13
to orient-...@googlegroups.com
Thank you Luca.  Is there a way to traverse N levels recursively using this model?  For instance, I want to get the entire tree in this case, but in other cases I may want to get, say, 6 hops as it grows.  This query seems to only provide the immediate parents/children.  I tried "TRAVERSE * FROM (SELECT FROM V WHERE name='Me')" as well, but that also has the invalid edge ids.  If there isn't an easy solution, I'll just create a proxy that rewrites the edge ids as a sequence.

Thanks,

Brian

Luca Garulli

unread,
Oct 7, 2013, 4:28:46 PM10/7/13
to orient-...@googlegroups.com
Hi Brian,
sorry I wrote the select statement instead of traverse. This is the traverse:

TRAVERSE both("IsParentOf") FROM (
  SELECT FROM V WHERE name='Me'
) WHILE $depth <= 6

if you want the 

SELECT expand(rel) FROM (
  TRAVERSE both("IsParentOf") as rels FROM (
    SELECT FROM V WHERE name='Me'
  ) WHILE $depth <= 6
)

Lvc@
Brian

--
 
---
You received this message because you are subscribed to the Google Groups "OrientDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to orient-databa...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Brian O'Keefe

unread,
Oct 9, 2013, 2:49:52 PM10/9/13
to orient-...@googlegroups.com
Luca,

I worked around this issue by writing a proxy that intercepts the JSON being returned and substitutes a unique id for the edge id.  However, that is not optimal and I tested this situation again using your suggestion of rewriting the query to:

TRAVERSE * FROM (SELECT FROM V WHERE name='Me')


{"an":{"#11:2":{"name":"Paternal Grandfather"}}}
{"an":{"#11:1":{"name":"Maternal Grandmother"}}}
{"an":{"#11:0":{"name":"Maternal Grandfather"}}}
{"an":{"#11:7":{"name":"Junior"}}}
{"an":{"#11:6":{"name":"Me"}}}
{"an":{"#11:5":{"name":"Dad"}}}
{"an":{"#11:4":{"name":"Mom"}}}
{"an":{"#11:3":{"name":"Paternal Grandmother"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:5","target":"#11:3"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:6","target":"#11:5"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:6","target":"#11:4"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:7","target":"#11:6"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:4","target":"#11:0"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:4","target":"#11:1"}}}
{"ae":{"#-1:-1":{"directed":false,"source":"#11:5","target":"#11:2"}}}

Thanks,

Brian
To unsubscribe from this group and stop receiving emails from it, send an email to orient-database+unsubscribe@googlegroups.com.

Luca Garulli

unread,
Oct 9, 2013, 2:58:28 PM10/9/13
to orient-database
Hi Brian,
I think that output is because the edges are lightweight, namely have no identity. You can avoid this with performance penalty by using:

alter database custom useLightweightEdges=false
Or you can pull last "develop" branch (or last 1.6.0-SNAPSHOT) where this has been fixed.

Lvc@

Brian O'Keefe

unread,
Oct 10, 2013, 9:28:44 AM10/10/13
to orient-...@googlegroups.com
Thanks Luca.  I'll probably just wait for 1.6 general release and use my proxy for the proof of concept.

sachchidanand singh

unread,
Aug 27, 2014, 7:16:39 AM8/27/14
to orient-...@googlegroups.com
Hi All,

I am facing the same issue, I am limiting my traversal, but the result which I am getting is unexpected, It shows the nodes according to the limit i have provided but along with this it is showing all the links connected to these nodes, for example if i have traversed to depth <=1 and limited it by 10, but actually this node is connected with 100 other nodes(lets say), then it will give result as all the 100 links along with these 10 nodes even though i have queried for 10 only. so is there any way which can restrict the unexpected links and i will get the only those links which are falling in to my traversal. 
I am using 1.6.0 SNAPSHOT and gephi end point.

Thanks,
Sachchidanand singh

Luca Garulli

unread,
Aug 27, 2014, 8:43:35 AM8/27/14
to orient-database
Hi Sachchidanand,
To understand what you did the query could help. Can you write it here?

Lvc@


For more options, visit https://groups.google.com/d/optout.

sachchidanand singh

unread,
Aug 27, 2014, 9:37:46 AM8/27/14
to orient-...@googlegroups.com
Hi Lvc@,

Below is the query i am using - 
select  from (traverse in('extracted_place') from (select from ExtractedLocation where name ='Gaza') while $depth <= 1) where not (isReTweet=true) limit 50

after encoding with gephi end point - 

if you break this query, it should give me the result of max 51 nodes (50 limit is given for outer query and 1 node for inner query) and connected 51 edges which shows their relationships. This limit is working fine for nodes and giving me expected nodes but it is giving those links also which are not the part of this traversal.
Lets say if these 50 nodes (which are getting traversed through outer query and are connected with one node of inner wuery) are connected with some other 100 nodes, since i am traversing till these 50 nodes (restricted by depth) so I am expecting only 50 links which are connecting these nodes to the central nodes but it is giving the other 100 links also which is not required and have not been asked.

Below is the result - 

{"an":{"#12:445320":{"content":"http://goo.gl/h5NfEI\u000ahttp://goo.gl/XZWrgW\u000aGaza\u000aIn this cold desolate hour\u000aKeep warm\u000aBurn a cere in Australia that is effectivee ...","sentiment":-0.10591847,"time":1408458600000,"content_id":"wbMdgQfUAGc","source":"youtube","relevance":5.795923,"contentURL":"http://www.youtube.com/watch?v=wbMdgQfUAGc"}}}
{"an":{"#12:505677":{"content":"#Demonstration for #Gaza, 23 August, Saturday #DowningStreet #London #Westminster #palestine @antizio_ @yvonneridley http://t.co/nBdyNiUUpP","sentiment":0.0,"time":1408554524000,"content_id":"502140188643319809","source":"Twitter","relevance":247.5,"language":"en","contentURL":"www.twitter.com/BarbiRashid/status/502140188643319809"}}}
{"an":{"#12:387378":{"content":"\u25b6 Sid Ryan speaking at Protest for Gaza, August 9, 2014 \u2013 YouTube http://t.co/TIrgFH1PUH","sentiment":-0.33333334,"time":1407759102000,"content_id":"498803943234076672","source":"Twitter","relevance":86.166664,"language":"en","contentURL":"www.twitter.com/QaisGhanem/status/498803943234076672"}}}
{"an":{"#12:428264":{"content":"http://goo.gl/h5NfEI\u000ahttp://goo.gl/XZWrgW\u000aGaza\u000aIn this cold desolate hour\u000aKeep warm\u000aBurn a can","sentiment":-0.10591847,"time":1408409659000,"content_id":"6Z4DtoKy4YQ","source":"youtube","relevance":5.795923,"contentURL":"http://www.youtube.com/watch?v=6Z4DtoKy4YQ"}}}
{"an":{"#12:515383":{"content":"#Demonstration for #Gaza, 23 August, Saturday #DowningStreet #boycott @BDSmovement @ReemKelani @YasinDin #ICC4Israel http://t.co/Xd3QeAt2Qi","sentiment":0.0,"time":1408554939000,"content_id":"502141928448589824","source":"Twitter","relevance":102.5,"language":"en","contentURL":"www.twitter.com/BarbiRashid/status/502141928448589824"}}}
{"an":{"#12:361554":{"content":"#Bangladesh #Jamaat-e islami demonstrations rally today in Dhaka, against the Israeli barbaric genocide on in #Gaza! http://t.co/3dc8hAx1gw","sentiment":-0.5,"time":1407738652000,"content_id":"498718170019278848","source":"Twitter","relevance":142.0,"language":"en","contentURL":"www.twitter.com/kewshukhinoy/status/498718170019278848"}}}
{"an":{"#12:512955":{"content":"#Demonstration for #Gaza, 23 August, Saturday #DowningStreet @georgegalloway @jvplive @TraditionalJews @TorahJews http://t.co/c1ecC5Ve0p","sentiment":0.0,"time":1408554822000,"content_id":"502141435077222400","source":"Twitter","relevance":106.0,"language":"en","contentURL":"www.twitter.com/BarbiRashid/status/502141435077222400"}}}
{"an":{"#16:2":{"name":"Gaza"}}}
{"an":{"#12:519499":{"content":"#Demonstration for #Gaza, 23 August, Saturday #DowningStreet @benabyad @Remroum @MaxBlumenthal @SaveGazaProject http://t.co/jDTisPhYMM","sentiment":0.0,"time":1408555183000,"content_id":"502142948973502464","source":"Twitter","relevance":112.0,"language":"en","contentURL":"www.twitter.com/BarbiRashid/status/502142948973502464"}}}
{"an":{"#12:407414":{"content":"Police arrest two men after ","sentiment":-0.105240874,"time":1408081610000,"content_id":"9abDQbd7U6E","source":"youtube","relevance":5.7620435,"contentURL":"http://www.youtube.com/watch?v=9abDQbd7U6E"}}}
{"an":{"#12:267322":{"content":"Stand together for Gaza demonstration Edinburgh Saturday 9 August, 2pm, In solidarity with the Palestinian people,  Assemble top of Mound","sentiment":0.45883146,"time":1407508761000,"content_id":"497753939966963712","source":"Twitter","relevance":106.941574,"language":"en","contentURL":"www.twitter.com/PCS_Scotland/status/497753939966963712"}}}
{"an":{"#12:277711":{"content":"Photo: hadaes: theworldstandswithpalestine: Melbourne protest for Gaza, July 19. 2014. everyone fucking... http://t.co/pWtj1beALN","sentiment":-0.42426407,"time":1407516638000,"content_id":"497786977060937729","source":"Twitter","relevance":79.7132,"language":"en","contentURL":"www.twitter.com/nic_ftw/status/497786977060937729"}}}
{"an":{"#12:376770":{"content":"Poignant message by a Congress worker at rally to protest against the killings in Gaza on Saturday, Aug 9 http://t.co/64iGHM6FmC","sentiment":0.0,"time":1407745778000,"content_id":"498748059677777920","source":"Twitter","relevance":90.5,"language":"en","contentURL":"www.twitter.com/wb_pcc/status/498748059677777920"}}}
{"an":{"#12:332947":{"content":"A special \"good morning\" to all those people who are London-bound to protest at the carnage taking place in Gaza. Well done to all of you.","sentiment":-0.07779408,"time":1407565366000,"content_id":"497991357051727872","source":"Twitter","relevance":64.3897,"language":"en","contentURL":"www.twitter.com/reddeviljp/status/497991357051727872"}}}
{"ae":{"#18:136->#12:332947":{"directed":false,"source":"#12:332947","target":"#18:136"}}}
{"ae":{"#12:332947->#13:247444":{"directed":false,"source":"#13:247444","target":"#12:332947"}}}
{"ae":{"#18:152->#12:376770":{"directed":false,"source":"#12:376770","target":"#18:152"}}}
{"ae":{"#12:376770->#15:28":{"directed":false,"source":"#15:28","target":"#12:376770"}}}
{"ae":{"#12:376770->#13:278674":{"directed":false,"source":"#13:278674","target":"#12:376770"}}}
{"ae":{"#18:4->#12:277711":{"directed":false,"source":"#12:277711","target":"#18:4"}}}
{"ae":{"#12:277711->#13:208623":{"directed":false,"source":"#13:208623","target":"#12:277711"}}}
{"ae":{"#12:267322->#15:0":{"directed":false,"source":"#15:0","target":"#12:267322"}}}
{"ae":{"#12:267322->#13:201174":{"directed":false,"source":"#13:201174","target":"#12:267322"}}}
{"ae":{"#12:267322->#16:1":{"directed":false,"source":"#16:1","target":"#12:267322"}}}
{"ae":{"#12:267322->#16:0":{"directed":false,"source":"#16:0","target":"#12:267322"}}}
{"ae":{"#18:0->#12:267322":{"directed":false,"source":"#12:267322","target":"#18:0"}}}
{"ae":{"#18:1->#12:267322":{"directed":false,"source":"#12:267322","target":"#18:1"}}}
{"ae":{"#18:2->#12:267322":{"directed":false,"source":"#12:267322","target":"#18:2"}}}
{"ae":{"#12:407414->#13:171731":{"directed":false,"source":"#13:171731","target":"#12:407414"}}}
{"ae":{"#12:407414->#15:13":{"directed":false,"source":"#15:13","target":"#12:407414"}}}
{"ae":{"#12:407414->#15:12":{"directed":false,"source":"#15:12","target":"#12:407414"}}}
{"ae":{"#12:407414->#16:60":{"directed":false,"source":"#16:60","target":"#12:407414"}}}
{"ae":{"#18:78->#12:407414":{"directed":false,"source":"#12:407414","target":"#18:78"}}}
{"ae":{"#18:104->#12:407414":{"directed":false,"source":"#12:407414","target":"#18:104"}}}
{"ae":{"#18:415->#12:519499":{"directed":false,"source":"#12:519499","target":"#18:415"}}}
{"ae":{"#12:519499->#13:200252":{"directed":false,"source":"#13:200252","target":"#12:519499"}}}
{"ae":{"#12:528388->#16:2":{"directed":false,"source":"#16:2","target":"#12:528388"}}}
{"ae":{"#12:519499->#16:2":{"directed":false,"source":"#16:2","target":"#12:519499"}}}
{"ae":{"#12:519338->#16:2":{"directed":false,"source":"#16:2","target":"#12:519338"}}}
{"ae":{"#12:516933->#16:2":{"directed":false,"source":"#16:2","target":"#12:516933"}}}
{"ae":{"#12:510447->#16:2":{"directed":false,"source":"#16:2","target":"#12:510447"}}}
{"ae":{"#12:407414->#16:2":{"directed":false,"source":"#16:2","target":"#12:407414"}}}
{"ae":{"#12:376770->#16:2":{"directed":false,"source":"#16:2","target":"#12:376770"}}}
{"ae":{"#12:332947->#16:2":{"directed":false,"source":"#16:2","target":"#12:332947"}}}
{"ae":{"#18:248->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:248"}}}
{"ae":{"#18:263->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:263"}}}
{"ae":{"#18:252->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:252"}}}
{"ae":{"#18:136->#12:387378":{"directed":false,"source":"#12:387378","target":"#18:136"}}}
{"ae":{"#12:387378->#14:4588":{"directed":false,"source":"#14:4588","target":"#12:387378"}}}
{"ae":{"#12:387378->#16:2":{"directed":false,"source":"#16:2","target":"#12:387378"}}}
{"ae":{"#12:387378->#15:29":{"directed":false,"source":"#15:29","target":"#12:387378"}}}
{"ae":{"#12:387378->#13:285641":{"directed":false,"source":"#13:285641","target":"#12:387378"}}}
{"ae":{"#18:415->#12:505677":{"directed":false,"source":"#12:505677","target":"#18:415"}}}
{"ae":{"#12:505677->#16:2":{"directed":false,"source":"#16:2","target":"#12:505677"}}}
{"ae":{"#12:505677->#12:510447":{"directed":false,"source":"#12:510447","target":"#12:505677"}}}
{"ae":{"#12:505677->#13:200252":{"directed":false,"source":"#13:200252","target":"#12:505677"}}}
{"ae":{"#12:445320->#13:324694":{"directed":false,"source":"#13:324694","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5619":{"directed":false,"source":"#14:5619","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5618":{"directed":false,"source":"#14:5618","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5617":{"directed":false,"source":"#14:5617","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5616":{"directed":false,"source":"#14:5616","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5615":{"directed":false,"source":"#14:5615","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5614":{"directed":false,"source":"#14:5614","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5613":{"directed":false,"source":"#14:5613","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5612":{"directed":false,"source":"#14:5612","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5611":{"directed":false,"source":"#14:5611","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5610":{"directed":false,"source":"#14:5610","target":"#12:445320"}}}
{"ae":{"#12:445320->#14:5609":{"directed":false,"source":"#14:5609","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:2":{"directed":false,"source":"#16:2","target":"#12:445320"}}}
{"ae":{"#18:243->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:243"}}}
{"ae":{"#18:248->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:248"}}}
{"ae":{"#18:254->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:254"}}}
{"ae":{"#18:252->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:252"}}}
{"ae":{"#18:246->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:246"}}}
{"ae":{"#18:247->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:247"}}}
{"ae":{"#18:244->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:244"}}}
{"ae":{"#18:273->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:273"}}}
{"ae":{"#18:267->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:267"}}}
{"ae":{"#18:266->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:266"}}}
{"ae":{"#18:263->#12:445320":{"directed":false,"source":"#12:445320","target":"#18:263"}}}
{"ae":{"#12:445320->#16:5":{"directed":false,"source":"#16:5","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:12":{"directed":false,"source":"#16:12","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:16":{"directed":false,"source":"#16:16","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:33":{"directed":false,"source":"#16:33","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:50":{"directed":false,"source":"#16:50","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:59":{"directed":false,"source":"#16:59","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:141":{"directed":false,"source":"#16:141","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:142":{"directed":false,"source":"#16:142","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:143":{"directed":false,"source":"#16:143","target":"#12:445320"}}}
{"ae":{"#12:445320->#16:144":{"directed":false,"source":"#16:144","target":"#12:445320"}}}
{"ae":{"#12:445320->#15:52":{"directed":false,"source":"#15:52","target":"#12:445320"}}}
{"ae":{"#12:445320->#15:53":{"directed":false,"source":"#15:53","target":"#12:445320"}}}
{"ae":{"#18:247->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:247"}}}
{"ae":{"#18:246->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:246"}}}
{"ae":{"#18:254->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:254"}}}
{"ae":{"#18:267->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:267"}}}
{"ae":{"#18:266->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:266"}}}
{"ae":{"#18:244->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:244"}}}
{"ae":{"#18:243->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:243"}}}
{"ae":{"#18:273->#12:428264":{"directed":false,"source":"#12:428264","target":"#18:273"}}}
{"ae":{"#12:428264->#16:2":{"directed":false,"source":"#16:2","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:5":{"directed":false,"source":"#16:5","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:12":{"directed":false,"source":"#16:12","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:16":{"directed":false,"source":"#16:16","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:33":{"directed":false,"source":"#16:33","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:50":{"directed":false,"source":"#16:50","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:59":{"directed":false,"source":"#16:59","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:141":{"directed":false,"source":"#16:141","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:142":{"directed":false,"source":"#16:142","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:143":{"directed":false,"source":"#16:143","target":"#12:428264"}}}
{"ae":{"#12:428264->#16:144":{"directed":false,"source":"#16:144","target":"#12:428264"}}}
{"ae":{"#12:428264->#15:52":{"directed":false,"source":"#15:52","target":"#12:428264"}}}
{"ae":{"#12:428264->#15:53":{"directed":false,"source":"#15:53","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5070":{"directed":false,"source":"#14:5070","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5071":{"directed":false,"source":"#14:5071","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5072":{"directed":false,"source":"#14:5072","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5073":{"directed":false,"source":"#14:5073","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5074":{"directed":false,"source":"#14:5074","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5075":{"directed":false,"source":"#14:5075","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5076":{"directed":false,"source":"#14:5076","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5077":{"directed":false,"source":"#14:5077","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5078":{"directed":false,"source":"#14:5078","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5079":{"directed":false,"source":"#14:5079","target":"#12:428264"}}}
{"ae":{"#12:428264->#14:5080":{"directed":false,"source":"#14:5080","target":"#12:428264"}}}
{"ae":{"#12:428264->#13:313798":{"directed":false,"source":"#13:313798","target":"#12:428264"}}}
{"ae":{"#12:515383->#13:200252":{"directed":false,"source":"#13:200252","target":"#12:515383"}}}
{"ae":{"#12:515383->#12:519338":{"directed":false,"source":"#12:519338","target":"#12:515383"}}}
{"ae":{"#12:515383->#16:2":{"directed":false,"source":"#16:2","target":"#12:515383"}}}
{"ae":{"#18:415->#12:515383":{"directed":false,"source":"#12:515383","target":"#18:415"}}}
{"ae":{"#18:147->#12:361554":{"directed":false,"source":"#12:361554","target":"#18:147"}}}
{"ae":{"#18:146->#12:361554":{"directed":false,"source":"#12:361554","target":"#18:146"}}}
{"ae":{"#12:361554->#16:102":{"directed":false,"source":"#16:102","target":"#12:361554"}}}
{"ae":{"#12:361554->#16:2":{"directed":false,"source":"#16:2","target":"#12:361554"}}}
{"ae":{"#12:361554->#13:268419":{"directed":false,"source":"#13:268419","target":"#12:361554"}}}
{"ae":{"#12:512955->#13:200252":{"directed":false,"source":"#13:200252","target":"#12:512955"}}}
{"ae":{"#12:512955->#12:516933":{"directed":false,"source":"#12:516933","target":"#12:512955"}}}
{"ae":{"#12:512955->#16:2":{"directed":false,"source":"#16:2","target":"#12:512955"}}}
{"ae":{"#18:415->#12:512955":{"directed":false,"source":"#12:512955","target":"#18:415"}}}
{"ae":{"#12:267322->#16:2":{"directed":false,"source":"#16:2","target":"#12:267322"}}}
{"ae":{"#12:277711->#16:2":{"directed":false,"source":"#16:2","target":"#12:277711"}}} 

here if you see, according to my query I should get only those links which are in to the central node, I have given 'extracted_by' edge name to connecting link between these two nodes. So according to my DB structure I should get link which shows the relationship of "#16 and #12"  but I am getting #14, #15, #18 also.
Because of this it is taking lot of time to execute the query, for some of the nodes I have more than 5k connecting nodes, so if you can suggest any way out to rid of this it will be very helpful to me.
please let me know if any clarification is needed.

Thanks

Brian O'Keefe

unread,
Aug 27, 2014, 9:45:54 AM8/27/14
to orient-...@googlegroups.com

I've seen this issue too.  It isn't an easy problem to fix.  I created my own service that 1. Uses the API to perform the desired function, but requires you to track visited nodes and depth to know when you reached the desired hops, and 2. Streams back the results to improve performance.  I didn't commit it back because it relies on jax-rs, cxf and spring, but I'll see if I can post the code tomorrow when I am back in the office.

You received this message because you are subscribed to a topic in the Google Groups "OrientDB" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/orient-database/3AUBqkNM5ks/unsubscribe.
To unsubscribe from this group and all its topics, send an email to orient-databa...@googlegroups.com.

@sach

unread,
Aug 27, 2014, 9:56:23 AM8/27/14
to orient-...@googlegroups.com
Thanks Brian for quick reply,

I'll wait till tomorrow for you to come back, I need some solution to overcome on this since I am facing lot of challenges.

@sach

unread,
Aug 28, 2014, 6:37:49 AM8/28/14
to orient-...@googlegroups.com
Hi Luca/Brian, 

Please let me know if you have any solution for this.


{"an":{"#11:0":</span
...

Brian O'Keefe

unread,
Aug 28, 2014, 9:06:53 AM8/28/14
to orient-...@googlegroups.com
NOTE:  This code is being provided as a reference and is completely without warranty.  It is informally tested, prototype code and not production quality. I can answer questions on a best effort basis, but there is no implied support with providing this.

The code below addresses 3 issues with the current Gephi interface:
1.  It tracks the visited nodes and only adds edges to those nodes which are in the result set.
2.  It streams the nodes and edges as they are visited rather than queuing the entire request to the end.
3.  In the current plugin, fields that persist into JSON objects are omitted in Gephi.  This will flatten maps and sets to a delimited string, so Gephi will display them.

The code below uses the following dependencies besides OrientDB:

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>2.7.7</version>       
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>2.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>

Spring config:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
         http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

<jaxrs:server id="gephiService" address="http://0.0.0.0:8089/">
    <jaxrs:serviceBeans>
        <bean class="full.namespace.to.TEMP" />
    </jaxrs:serviceBeans>
</jaxrs:server>

</beans>

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientEdge;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;

public class TEMP {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    static OrientGraphFactory factory = null;

    private void init() {
        factory = new OrientGraphFactory("CONNECTION STRING", "USERNAME", "PASSWORD").setupPool(1,10);
    }
   
    @GET
    @Path("{productType}/{id}")
    @Produces("application/json")
    public Response getNode(final @PathParam("id") String id, final @QueryParam("maxHops") @DefaultValue("1") int maxHops, final @QueryParam("excludeClass") List<String> excludeClasses, final @QueryParam("nodeSize") @DefaultValue("3") int nodeSize, final @QueryParam("minEdges") @DefaultValue("1") int minNumberOfEdges, final @QueryParam("label") @DefaultValue("name") String labelField) {
               
        if (factory == null) {
            init();
        }
       
        final StreamingOutput stream = new StreamingOutput() {
            @Override
            public void write(OutputStream os) throws IOException, WebApplicationException {
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));

                OrientGraphNoTx graph = factory.getNoTx();
               
                try {
                    String query = "SELECT FROM V WHERE myId=" + id;
                   
                    @SuppressWarnings("unchecked")
                    Iterator<Vertex> iter = ((Iterable<Vertex>)graph.command(new OCommandSQL(query)).execute()).iterator();

                    while(iter.hasNext()) {
                        OrientVertex v = (OrientVertex)iter.next();
                       
                        Set<String> visitedNodes = new HashSet<String>();
                        visitedNodes.add(v.getId().toString());
                       
                        // write current vertex
                        writer.write(vertexToJSON(v, nodeSize, labelField).toString());
                        writer.write("\r");
                       
                        logger.info("Max Hops is {}", maxHops);
                       
                        processVertex(v, writer, new HashSet<String>(), new HashSet<String>(), 0, maxHops, excludeClasses, nodeSize, minNumberOfEdges, labelField);
                    }


                } catch (JSONException e) {
                    logger.error("JSON error", e);
                    throw new javax.ws.rs.MessageProcessingException(e);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    logger.error("Unknown error", e);
                    throw new javax.ws.rs.BadRequestException(e);               
                }

                writer.flush();
            };
        };
       
           
        return Response.ok(stream).header("Connection", "Keep-Alive").encoding("UTF-8").build();
    }
   
    private void processVertex(OrientVertex vertex, BufferedWriter writer, Set<String> visitedNodes, Set<String> visitedEdges, int currentHop, int maxHops, List<String> excludeClasses, int nodeSize, int minEdges, String labelField) throws JSONException, IOException {

       
        boolean isAtEdge = (currentHop >= maxHops);
       
        logger.info("Processing {} on hop {} (max: {})", vertex.getId().toString(), currentHop, maxHops);       
       
        // write immediate siblings
        logger.debug("Checking siblings");
        int count = 0;
        Iterator<Vertex> siblings = vertex.getVertices(Direction.BOTH).iterator();
        while(siblings.hasNext()) {
            count++;
            Set<OrientVertex> nodesToProcess = new HashSet<OrientVertex>();
            Set<OrientVertex> nodesToComputeEdges = new HashSet<OrientVertex>();

            OrientVertex sibling = (OrientVertex)siblings.next();
            logger.info("Sibling {} of {} is {}", count, vertex.getId().toString(), sibling.getId().toString());
           
            if (!isAtEdge || visitedNodes.contains(sibling.getId().toString())) {
                logger.info("Added {} to compute edges", sibling.getId().toString());
                nodesToComputeEdges.add(sibling);
            }
           
            // only write the node if we haven't seen this guy yet and haven't reached the max hops
            if (
                    !
                    (
                        isAtEdge
                        || visitedNodes.contains(sibling.getId().toString())
                        || (
                            excludeClasses != null
                            && excludeClasses.size() > 0
                            && excludeClasses.contains(sibling.getLabel())
                        )
                        || (sibling.countEdges(Direction.BOTH) < minEdges)
                    )
                )
            {                               
                writer.write(vertexToJSON(sibling, nodeSize, labelField).toString());
                writer.write("\r");
                writer.flush();
                logger.info("Wrote {} to stream and added to visited", sibling.getId().toString());
                visitedNodes.add(sibling.getId().toString());
                nodesToProcess.add(sibling);
            }

            Map<String, JSONObject> edges = new HashMap<String, JSONObject>();
           
            // get the sibling edges
            for(OrientVertex nextVertex : nodesToComputeEdges) {
                logger.info("Checking sibling edges for {} from {}", nextVertex.getId().toString(), vertex.getId().toString());
               
                if (visitedNodes.contains(nextVertex.getId().toString())) {

                    Iterator<Edge> iter = vertex.getEdges(nextVertex, Direction.BOTH).iterator();
                    while(iter.hasNext()) {
                        OrientEdge edge = (OrientEdge) iter.next();
                        OrientVertex inVertex = (OrientVertex)edge.getVertex(Direction.IN);
                        OrientVertex outVertex = (OrientVertex)edge.getVertex(Direction.OUT);
                        logger.info("Inspecting edge {} -> {} ({})", inVertex.getId().toString(), outVertex.getId().toString(), edge.getLabel());
                       
                        String edgeId = inVertex.getId().toString() + "->" + outVertex.getId().toString();
                        if (!visitedEdges.contains(edgeId)) {
                            logger.info("Adding edge {}", edgeId);
                           
                            JSONObject edgeProps = new JSONObject();
                            edgeProps.put("directed", "false");
                            edgeProps.put("source", inVertex.getId().toString());
                            edgeProps.put("target", outVertex.getId().toString());
                            edgeProps.put("type", edge.getLabel());
                            edgeProps.put("label", edge.getLabel());
           
                            if (!edge.isLightweight()) {
                                for(String key : edge.getPropertyKeys()) {
                                    logger.debug("Property key: {}", key);
                                    String value = flattenProperty(edge.getProperty(key));
                                    logger.debug("Property value: {}", value);
                                    edgeProps.put(key, value);
                                }
                            }
                           
                            JSONObject edgeNode = new JSONObject();
                            edgeNode.put(edgeId, edgeProps);
                            JSONObject edgeRoot = new JSONObject();
                            edgeRoot.put("ae", edgeNode);
                            logger.debug(edgeRoot.toString());
                           
                            logger.info("Adding {} to stream", edgeId);
                           
                            if (edges.containsKey(edgeId)) {
                                edges.put(edgeId, mergeEdges(edgeId, edgeRoot, edges.get(edgeId)));
                            } else {
                                edges.put(edgeId, edgeRoot);
                            }
                        }
                    }
                }
            }
           
            for(JSONObject edgeObj : edges.values()) {
                logger.info("Wrote {}", edgeObj.toString());
                writer.write(edgeObj.toString());
                writer.write("\r");
                writer.flush();
               
            }
            visitedEdges.addAll(edges.keySet());

            if (!isAtEdge) {
                logger.info("{} nodes to process", nodesToProcess.size());
                for(OrientVertex nextVertex : nodesToProcess) {
                    logger.info("Calling ProcessVertex({})", nextVertex.getId().toString());
                    processVertex(nextVertex, writer, visitedNodes, visitedEdges, currentHop + 1, maxHops, excludeClasses, nodeSize, minEdges, labelField);
                }
            }
           
        }
               
    }

   
    private JSONObject vertexToJSON(OrientVertex vertex, int nodeSize, String labelField) throws JSONException {
        String id = vertex.getId().toString();
        JSONObject root = new JSONObject();
        logger.info("Adding node {}", id);
        JSONObject properties = new JSONObject();
        for(String key : vertex.getPropertyKeys()) {
            logger.debug("Property key: {}", key);
            String value = flattenProperty(vertex.getProperty(key));
            logger.debug("Property value: {}", value);
            properties.put(key, value);
        }
        properties.put("nodeType", vertex.getLabel());
        logger.debug("vertex type is {}", vertex.getLabel());
        properties.put("label", vertex.getProperty(labelField).toString());
        properties.put("color", "0x000000");
        properties.put("size", nodeSize);
        JSONObject node = new JSONObject();
        node.put(id, properties);
        root.put("an", node);
       
        return root;
    }
   
    private String flattenProperty(Object property) {
        if (property instanceof Set) {
            StringBuilder sb = new StringBuilder();
            @SuppressWarnings("unchecked")
            Set<Object> set = (Set<Object>)property;
            for(Object setItem : set) {
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(setItem.toString());
            }
            return sb.toString();
        } if (property instanceof Map) {
            StringBuilder sb = new StringBuilder();
            @SuppressWarnings("unchecked")
            Map<String,Object> map = (Map<String,Object>)property;
            for(String mapKey : map.keySet()) {
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(mapKey + "=>" + map.get(mapKey).toString());
                return sb.toString();
            }
        } else {
            logger.debug("Property is type {}", property.getClass().getName());
            return property.toString();
        }
        return "";
    }
   
    private JSONObject mergeEdges(String edgeName, JSONObject mergee, JSONObject merger) throws JSONException {
        JSONObject mergeeProps = mergee.getJSONObject("ae").getJSONObject(edgeName);
        JSONObject mergerProps = merger.getJSONObject("ae").getJSONObject(edgeName);
        JSONObject returnVal = mergee;
       
        logger.debug("Merging edge {}", edgeName);
       
        @SuppressWarnings("rawtypes")
        Iterator iter = mergerProps.keys();
        while(iter.hasNext()) {
            String key = iter.next().toString();
            String mergeeValue = mergeeProps.optString(key);
            String mergerValue = mergerProps.optString(key);
           
            logger.debug("merging key: {}", key);
            logger.debug("mergee value is {}", mergeeValue);
            logger.debug("merger value is {}", mergerValue);

            if (mergeeValue == null) {
                logger.debug("mergee doesn't have {}, setting to {}", key, mergerValue);
                mergeeValue = mergerValue;
            } else if (!mergeeValue.equals(mergerValue)) {
                logger.debug("meshing {}: {} and {}, setting to {}", key, mergeeValue, mergerValue, mergeeValue + "; " + mergerValue);
                mergeeValue += "; " + mergerValue;
            }
           
            returnVal.getJSONObject("ae").getJSONObject(edgeName).put(key, mergeeValue);
        }
       
        return returnVal;
</di
...
Reply all
Reply to author
Forward
0 new messages