Matching on nested objects


#1

If I have the following set of tuples:

<User> <likes> <Pizza> .
<User> <likes> <Dinner> .
<User> <likes> <Coffee> .
<Dinner> <is> <Steak> .
<Steak> <is> <Food> .
<Pizza> <is> <Food> .
<Coffee> <is> <Beverage> .
<predicates> <are> <likes> .
<predicates> <are> <is> .

How do I find all of the <Food> (including objects that resolve to <Food> through <is>) that <User> <likes>?

A super basic Gizmo query that returns “top-level” <likes> is:

g.V('<User>').out('<likes>').has('<is>', '<Food>').all()

How would I include <Steak> in the result set (through <User> “liking” `)? Do I need to use some type of recursive query? Or is there a simpler way?

Thanks!


#2

This is a two-level solution:

g.V("<User>").out("<likes>").has('<is>', '<Food>').union(
    g.V("<User>").out("<likes>").out("<is>").has('<is>', '<Food>')
).all()

This is a recursive solution:

g.V("<User>").out("<likes>").has('<is>', '<Food>').union(
    g.V("<User>").out("<likes>").followRecursive("<is>").has("<is>", "<Food>")
).all()

#3

In general some tips about data modelling:

  1. Classes should start with capital letters (User, Food)
  2. In the basic cases properties should be between instances: (alice likes pizza)
  3. The standard way to declare an instance of class is:
    N-Quads: <alice> is <User>
    JSON-LD: { "@id": "alice", "@type": "User" }
  4. The standard way to declare subclasses of classes:
    N-Quads: <Dinner> rdfs:subClassOf <Food>
    JSON-LD { "@id": "Dinner", "rdfs:subClassOf": { "@id": "Food" } }

#4

This is great, thank you!

I was able to get close to the solution you provided by following along with this blog post (which seems to be down now?): http://blog.juganaru.eu/2016/06/28/google-cayley-graph-database-tutorial-family-tree/

Also, I appreciate the advice around data modeling/conventions… it’s likely obvious (:wink:) , but I’m just ramping up on graph dbs/rdf/linked data and am still wrapping my head around some of the concepts, so really appreciate the hints! :smiley: