Good or bad idea? Vertex with an edge pointing to another edge

118 views
Skip to first unread message

apoll...@gmail.com

unread,
Aug 22, 2015, 4:42:20 PM8/22/15
to OrientDB
Hi, I'm new to OrientDB and think it's extremely cool.

Here's a picture of what I'm asking about:



This graph shows:

* Bob likes Star Trek
* Joe likes the fact that Bob likes Star Trek

(The picture was made with the concept mapping software VUE, since I'm not yet sure how to display that graph with OrientDB's Studio.  http://vue.tufts.edu/ )

Starting with a new database, I can add the above data to OrientDB with these queries:

create vertex set name="Bob"
create vertex set name="Joe"
create vertex set name="Star Trek"

create edge from #9:0 to #9:2 set name="likes"
create edge from #9:1 to #10:0 set name = "likes"

Is this a good way of doing things?

Or are there any better ways to define relationships like these?

Is it bad to draw an edge from a vertex to another edge?

And, what queries should I use to display the above relationships in the OrientDB Studio visual graph?


Thanks for any answers!

Best wishes,
Apollia

apoll...@gmail.com

unread,
Aug 22, 2015, 5:36:44 PM8/22/15
to OrientDB
Sorry, I don't know why the picture didn't display.

Here's a URL instead:

http://astroblahhh.com/temporary__files/orient_db_group/OrientDB-Question-1.png

scott molinari

unread,
Aug 23, 2015, 4:17:15 AM8/23/15
to OrientDB
The image didn't work because the link is broken. The image throws a 403.

Scott

apoll...@gmail.com

unread,
Aug 23, 2015, 2:54:16 PM8/23/15
to OrientDB
On Sunday, August 23, 2015 at 4:17:15 AM UTC-4, scott molinari wrote:
The image didn't work because the link is broken. The image throws a 403.

Scott

Thanks for the info!  With my 1st post, I had dragged/dropped the image from my computer into the Google Groups post editor, and, since the image appeared in my editor, it looked like it was going to work.  Oh, well.


The link in my 2nd post works for me: http://astroblahhh.com/temporary__files/orient_db_group/OrientDB-Question-1.png

Archive.org also was able to access that link: https://web.archive.org/web/http://astroblahhh.com/temporary__files/orient_db_group/OrientDB-Question-1.png


But, in case the link from my 2nd post is also not working for some people, here's an ASCII art version of my picture:


|-----|             |-----------|
| Bob |----likes--->| Star Trek |
|-----|      ^      |-----------|
             |
             | likes
             |
          |-----|
          | Joe |
          |-----|


Explanation: Joe likes the fact that Bob likes Star Trek.

Here's a link to my original post, containing my questions: https://groups.google.com/d/msg/orient-database/NDrGteQLmf8/kOQ0gEZiBAAJ

Sorry for all the confusion!

Best wishes,
Apollia

Riccardo Tasso

unread,
Aug 23, 2015, 5:03:32 PM8/23/15
to orient-...@googlegroups.com
Hi,
   if you really need to model this scenario...I guess this is a good way to do it.

Which are the queries you'd like to answer?

Anyway this is somehow different from a graph database scenario and probably I would use the lower level Document API with LINKs.

Another possibility is to use what is called "reification" of your relation.
In your case create a class Statement, which extends Vertex.
A statement has always an outgoing edge labeled "subject" and another outgoing edge labeled "object".
The first statement (s1) has subject Bob and object Star Trek.
The second statement (s2) has subject Joe and object s1.
Each statement of course may have a label or type.

I prefer the reification solution, since you are compliant with the graph model.

Cheers,
   Riccardo

--

---
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/d/optout.

scott molinari

unread,
Aug 24, 2015, 2:08:35 AM8/24/15
to OrientDB
And in this scenario, S1 has a label called likes? So with S1, we are basically creating a vertex what connects two other vertices through the edges subject and object. I think I get it. 

I can imagine that abstract data model makes querying a bit more complicated, doesn't it? How would one query for exactly what it is that Joe is liking?

Scott

Riccardo Tasso

unread,
Aug 25, 2015, 3:12:40 AM8/25/15
to orient-...@googlegroups.com
I don't know if it's necessary separate "likes" which points to a statement from those pointing to something concrete (e.g. a movie).

Anyway you could always keep statements in a separate subclass (Statement) and "real objects" in another one (Concrete).

I'm thinking of something like:

SELECT in("subject").out("object")
FROM #1:1
WHERE in("subject").out("object") INSTANCEOF "Concrete"

I know it's a bit complicated, but it seems to me the simplest way to model it.

If you want to follow a chain of statements, without knowing a priori the depth level, you could also use a TRAVERSE.

Cheers,
   Riccardo

--

apoll...@gmail.com

unread,
Aug 25, 2015, 7:11:34 AM8/25/15
to OrientDB
Thank you for your very helpful replies, Riccardo and Scott!

I think I also prefer the reification solution and being fully compliant with the graph model.

From what I've read around the web so far, I've gotten the impression that graph databases are overall better than document databases.

So, from now on, I'll probably usually avoid drawing edges from vertexes to other edges.

And also avoid drawing edges between two edges, which I read elsewhere also isn't appropriate in a graph:

https://github.com/orientechnologies/orientdb/issues/4078

http://stackoverflow.com/questions/28781749/am-i-supposed-to-be-able-to-create-edges-between-two-edges-and-or-an-edge-and-a


The rest of this post contains no questions, just info for anyone curious.

Again, I'm a newbie, so, if anyone has any feedback, suggestions, etc., I'd love to read them!


Happily, my renovated, hopefully now compliant graph can now easily be displayed in OrientDB Studio's visual graph editor, just by running the query "select from v".

And I was able to figure out how to write some queries for my renovated graph.


I completed my renovations before seeing Riccardo's second post - https://groups.google.com/d/msg/orient-database/NDrGteQLmf8/3FKYU9UhBQAJ

So, I didn't include a "Concrete" class, just Riccardo's earlier ideas - vertexes of the "Statement" class and edges of classes "Subject" and "Object".  Thanks again, Riccardo!


I gave the Statement vertexes two properties: "name", which isn't used in queries and was just for display in my graph screenshot; and "verb", which is the property I used in some queries below.

Example name property from a Statement: "Bob likes Star Trek"

Example verb property from that Statement: "likes"


My renovated graph is now too big for me to easily make an ASCII art version, so, hopefully one or the other of these links will work:

http://astroblahhh.com/files_for_forums/OrientDB_Google_Group/Question_1/OrientDB-Question_1-Expanded_Graph.png

https://web.archive.org/web/20150825094101/http://astroblahhh.com/files_for_forums/OrientDB_Google_Group/Question_1/OrientDB-Question_1-Expanded_Graph.png


And, here's a DB export in JSON format, for anyone who wants to experiment with the data:

http://astroblahhh.com/files_for_forums/OrientDB_Google_Group/Question_1/apdb.json

https://web.archive.org/web/20150825094433/http://astroblahhh.com/files_for_forums/OrientDB_Google_Group/Question_1/apdb.json


Below are a bunch of queries I made.  They're largely pretty confusing, both to read and to write, but, this blog post showed me some of the syntax to use: http://orientdb.com/orientdb-improved-sql-filtering/

The official manual also helped: http://orientdb.com/docs/2.1/SQL.html

And lots of trial and error. :-)  Happily, I got much further than I thought I might, being a newbie to graph DBs. :-)  (With some familiarity with ordinary MySQL.)


This query gets all the subjects of Statements:

select expand( distinct(out('Subject').name ) ) from Statement

(Yields Bob, Joe and Jim.)


All the objects of Statements:

select expand( distinct(out('Object').name ) ) from Statement

(Yields "Star Trek", "Bob likes Star Trek", "Star Wars", "Joe's hat", "Jim likes Star Wars", "Jim's cup of tea", "Joe's spoon".)


All subjects who like something:

select distinct(out('Subject').name) from Statement where verb='likes'


(Yields "Bob", "Joe", "Jim".)


All subjects who have something:

select distinct(out('Subject').name) from Statement where verb='has'

(Yields "Joe", "Jim".)


All the Statements with the subject Joe:

select expand(in('Subject')[@class=Statement] ) from #9:1

(Yields "Joe likes Bob's like" (short for "Joe likes the fact that Bob likes Star Trek"), "Joe has a hat", "Joe likes Jim's like" (Joe likes the fact that Jim likes Star Wars), "Joe has a spoon".)


All Statements which say Joe likes something:

select expand(in('Subject')[@class=Statement][verb='likes'] ) from #9:1

(Yields "Joe likes Bob's like", "Joe likes Jim's like".)


All Statements which say Joe has something:

select expand(in('Subject')[@class=Statement][verb='has'] ) from #9:1


(Yields "Joe has a hat", "Joe has a spoon".)


All the things Joe is stated to have:

select expand(in('Subject')[@class=Statement][verb='has'].out('Object')) from #9:1

(Yields "Joe's hat", "Joe's spoon".)


All the things Joe is stated to like:

select expand(in('Subject')[@class=Statement][verb='likes'].out('Object')) from #9:1

(Yields "Bob likes Star Trek", "Jim likes Star Wars".)


All the things Jim is stated to like:

select expand(in('Subject')[@class=Statement][verb='likes'].out('Object')) from #9:3

(Yields "Star Wars", "Bob likes Star Trek".)


Everyone who likes the fact that Bob likes something:

select expand(in('Subject')[@class=Statement][verb='likes'].in('Object').out('Subject') ) from #9:0


(Yields "Joe", "Jim".)


----

Best wishes,
Apollia
Reply all
Reply to author
Forward
0 new messages