Syncleus / Ferma

An ORM / OGM for the TinkerPop graph stack.
http://syncleus.com/Ferma
Apache License 2.0
136 stars 26 forks source link

Allow @GraphElement to take a value #38

Closed sebeard closed 6 years ago

sebeard commented 6 years ago

Would it be possible to extend the GraphElement annotation to take in a String value (default "") that can be used to define a label of the Element/Edge/Vertex being created. If blank the simple class name could be used as a fallback.

freemo commented 6 years ago

You can already do this via the @Adjaency or @Incidence annotation. Is there any reason this isnt sufficient?

sebeard commented 6 years ago

Maybe I'm misusing or misunderstanding their usages. I do already use both these annotations.

From the example documentation;

public abstract class Person extends AbstractVertexFrame {
  @Property("name")
  public abstract String getName();

  @Property("name")
  public abstract void setName(String name);

  @Adjacency(label = "knows")
  public abstract List<Person> getKnowsPeople();

  @Incidence(label = "knows")
  public abstract List<Knows> getKnows();

  @Incidence(label = "knows")
  public abstract Knows addKnows(Person friend);

}

I understand that;

From what I've seen in debug (and I probably haven't delved deep enough) Vertices can also have labels, and Ferma uses the simple class name as the label of the vertex.

What I'm suggesting is that any class annotated with @GraphElement could use an optional label attached to it as the label rather than the class name, Ferma can still fall back to using the class name if the label value is not supplied. Think of it a little like Spring's @Component/@Service annotation where you can specify a value which "may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an autodetected component."

This isn't that important - it's more of a convenience value so I can represent a data model without exposing my class hierarchy or structure, and describe the graph exactly as designed.

freemo commented 6 years ago

@sebeard so depends what you mean by "label". In graph databases, and more specifically tinkerpop, only edges have labels. Verticies do have IDs but they have to be unique so don't really serve a similar purpose. You could create an arbitrary property called "label" and use that in a similar way that edges have label, but that isnt a concept built into gremlin or tinkerpop in any way.

The class name isnt currently used as a "label" but it is used to define the type that backs a class. It is effectively used to figure out which concrete class is used to instantiate an instance of the vertex. Edges have the same property with the same purpose. It is separate from a label though and serves a different function.

Is your intention just to define a different "type" name in the graph, something that replaces the class name? It wouldnt be a label and currently you'd have to do that by writing a custom type resolver. But that is something that could, in theory, be defined in the GraphElement annotation, but it wouldnt be a label regardless and behave very differently than an edge label might.

sebeard commented 6 years ago

@freemo Thanks for the great explanation. I think I started to grasp that having delved a bit deeper.

My intention was to effectively label the vertices similar to the edges. I think this is leftover understanding from when I was trying out the Gremlin-OGM project before noticing yours. OGM didn't quite cut it in terms of resolving to different type hierarchies.

One question though - I'm seeing in the tinkerpop documentation http://tinkerpop.apache.org/docs/3.3.0/reference/#label-step - (and specifically recipes - http://tinkerpop.apache.org/docs/current/recipes/#duplicate-edge) references to a hasLabel traversal which seems to refer to a label on a vertex. Could you explain that to me?

freemo commented 6 years ago

@sebeard so they are basically reusing the word "label" here to mean something entirely different from an edge label. When you do a Gremlin pipeline you can label any one step (effectively the group of vertex and edges represented by that step) with a specific label and then reference that label again later. for example when you see commands like as("a") at the link you sent me it creates the label "a" and assigned it to all the vertex and edges at that step. They are then later recalled when filtering with commands like by("a") and can be excluded or included in that particular step. None of that has anything to do with any label encoded into the graph itself however.

freemo commented 6 years ago

@sebeard Do we want to close this ticket, or are you requesting a feature whereby the type encoded into the graph can be customized?

sebeard commented 6 years ago

@freemo Great thanks!! I think this can be closed. Thanks for aiding my understanding.

hatemalimam commented 6 years ago

I'm little confused here, shouldn't all the Vertex be created in the Graph database in their corresponding label (Class.getName() for example) ? meaning if I create a framed vertex like this:

User julia = fg.addFramedVertex(User.class); julia.setName("Julia");

I get this in Neo4j

screen shot 2018-01-16 at 17 09 58

the vertex in the screenshot should be labeled as user, any specific reason why I'm getting this ? or is it the default behaviour of ferma ?

Is there any way to create a vertex with a label like the default approach in gremlin ?

Vertex peter = graph.addVertex(T.label, "user")

Which results with this:

screen shot 2018-01-16 at 17 15 21

hatemalimam commented 6 years ago

I managed to solve my issue with this:

User user = fg.addFramedVertex(User.DEFAULT_INITIALIZER, T.label, "user"); user.setName("Julia");