Hi,
Here are the 2 missing images.
The first is the property graph meta model as defined with gremlin.
public static Graph gremlinMetaModel() {
enum GremlinDataType {
STRING,
INTEGER,
DOUBLE,
DATE,
TIME
//...
}
TinkerGraph propertyGraphMetaModel = TinkerGraph.open();
Vertex graph = propertyGraphMetaModel.addVertex(T.label, "Graph",
"name", "GremlinDataType::STRING");
Vertex vertex = propertyGraphMetaModel.addVertex(T.label,
"VertexLabel", "label", "GremlinDataType::STRING");
Vertex edge = propertyGraphMetaModel.addVertex(T.label, "EdgeLabel",
"label", "GremlinDataType::STRING");
Vertex vertexProperty = propertyGraphMetaModel.addVertex(T.label,
"VertexProperty", "name", "GremlinDataType::STRING", "type", "GremlinDataType");
Vertex edgeProperty = propertyGraphMetaModel.addVertex(T.label,
"EdgeProperty", "name", "GremlinDataType::STRING", "type", "GremlinDataType");
graph.addEdge("vertices", vertex);
graph.addEdge("edges", edge);
vertex.addEdge("properties", vertexProperty);
vertex.addEdge("properties", edgeProperty);
vertex.addEdge("out", edge);
vertex.addEdge("in", edge);
return propertyGraphMetaModel;
}
propertyGraphMetaModel.png
The second is TinkerPop's modern model/schema also as defined with
gremlin.
public static Graph modernModel() {
//import this from a base package
enum GremlinDataType {
STRING,
INTEGER,
DOUBLE,
DATE,
TIME
//...
}
TinkerGraph modernModelGraph = TinkerGraph.open();
Vertex person = modernModelGraph.addVertex(T.label, "VertexLabel",
"label", "person");
Vertex personNameVertexProperty = modernModelGraph.addVertex(T.label,
"VertexProperty", "name", "name", "type", GremlinDataType.STRING.name());
Vertex personAgeVertexProperty = modernModelGraph.addVertex(T.label,
"VertexProperty", "name", "age", "type", GremlinDataType.INTEGER.name());
person.addEdge("properties", personNameVertexProperty);
person.addEdge("properties", personAgeVertexProperty);
Vertex software = modernModelGraph.addVertex(T.label, "VertexLabel",
"label", "software");
Vertex softwareNameVertexProperty = modernModelGraph.addVertex(T.label,
"VertexProperty", "name", "name", "type", GremlinDataType.STRING.name());
Vertex softwareLangVertexProperty = modernModelGraph.addVertex(T.label,
"VertexProperty", "name", "lang", "type", GremlinDataType.STRING.name());
software.addEdge("properties", softwareNameVertexProperty);
software.addEdge("properties", softwareLangVertexProperty);
Vertex knows = modernModelGraph.addVertex(T.label, "EdgeLabel",
"label", "knows");
Vertex knowsWeightVertexProperty = modernModelGraph.addVertex(T.label,
"EdgeProperty", "name", "weight", "type", GremlinDataType.INTEGER.name());
knows.addEdge("properties", knowsWeightVertexProperty);
Vertex created = modernModelGraph.addVertex(T.label, "EdgeLabel",
"label", "created");
Vertex createdWeightVertexProperty =
modernModelGraph.addVertex(T.label, "EdgeProperty", "name", "weight", "type",
GremlinDataType.INTEGER.name());
created.addEdge("properties", createdWeightVertexProperty);
person.addEdge("outEdge", knows);
person.addEdge("outEdge", created);
software.addEdge("inEdge", knows);
software.addEdge("inEdge", created);
return modernModelGraph;
}
modernModel.png
Regards
Pieter
On Sun, 2022-01-09 at 14:28 +0200, pieter gmail wrote:
> Hi,
>
> I have done some work on defining a meta model for Gremlin's property graph.
> I am using the approach used in the modelling world, in particular as done by
> the OMG group when defining their various meta models and specifications.
>
> However where OMG uses a subset of the UML to define their meta models I
> suggest we use Gremlin. After all Gremlin is the language we use to describe
> the world and the property graph meta model can also be described in Gremlin.
>
> I propose that we have 3 levels of modelling. Each of which can itself be
> specified in gremlin.
>
> 1: The property graph meta model.
> 2: The model.
> 3: The graph representing the actual data.
>
> 1) The property graph meta model describes the nature of the property graph
> itself. i.e. that property graphs have vertices, edges and properties.
>
> 2) The model is an instance of the meta model. It describes the schema of a
> particular graph. i.e. for TinkerPop's modern graph this would be 'person',
> 'software', 'created' and 'knows' and the various properties 'weight', 'age',
> 'name' and 'lang' properties.
>
> 3) The final level is an instance of the model. It is the actual graph
> itself. i.e. for TinkerPop's modern graph it is 'Marko', 'Josh', 'java' ...
>
>
> 1: Property Graph Meta Model
>
> public static Graph gremlinMetaModel() {
> enum GremlinDataType {
> STRING,
> INTEGER,
> DOUBLE,
> DATE,
> TIME
> //...
> }
> TinkerGraph propertyGraphMetaModel = TinkerGraph.open();
> Vertex graph = propertyGraphMetaModel.addVertex(T.label, "Graph",
> "name", "GremlinDataType::STRING");
> Vertex vertex = propertyGraphMetaModel.addVertex(T.label,
> "VertexLabel", "label", "GremlinDataType::STRING");
> Vertex edge = propertyGraphMetaModel.addVertex(T.label, "EdgeLabel",
> "label", "GremlinDataType::STRING");
> Vertex vertexProperty = propertyGraphMetaModel.addVertex(T.label,
> "VertexProperty", "name", "GremlinDataType::STRING", "type",
> "GremlinDataType");
> Vertex edgeProperty = propertyGraphMetaModel.addVertex(T.label,
> "EdgeProperty", "name", "GremlinDataType::STRING", "type", "GremlinDataType");
>
> graph.addEdge("vertices", vertex);
> graph.addEdge("edges", edge);
> vertex.addEdge("properties", vertexProperty);
> vertex.addEdge("properties", edgeProperty);
> vertex.addEdge("out", edge);
> vertex.addEdge("in", edge);
>
> return propertyGraphMetaModel;
> }
>
> This can be visualized as,
>
> Notes:
> 1) GremlinDataType is an enumeration of named data types that Gremlin
> supports. All gremlin data types are assumed to be atomic and its life cycle
> fully owned by its containing parent. How it is persisted on disc or
> transported over the wire is not a concern for the meta model.
> 2) Gremlin's semantics is to weak to fully specify a valid meta model.
> Accompanying the meta model we need a list of constraints specified as
> gremlin queries to augment the semantics of the meta model. These
> constraints/queries will be able to validate any gremlin specified model for
> correctness.
> 3) It is trivial to extend the meta model. e.g. To specify something like
> index support just add an 'Index' vertex and an edge from 'VertexLabel' to it.
>
> Property graph meta model constraints,
>
> 1) Every 'VertexLabel' must have a 'label'.
> g.V().hasLabel("EdgeLabel").where(__.not(__.in("inEdge"))).id()
> 2) Every 'EdgeLabel' must have a 'label'.
> g.V().hasLabel("EdgeLabel").or(__.hasNot("label"), __.has("label",
> P.eq(""))).id()
> 3) Every 'EdgeLabel' must have at least one 'outEdge' 'VertexLabel'
> g.V().hasLabel("EdgeLabel").where(__.not(__.in("outEdge"))).id()
> 4) Every 'EdgeLabel' must have at least on 'inEdge' 'VertexLabel'
> g.V().hasLabel("EdgeLabel").where(__.not(__.in("inEdge"))).id()
> 5) Every 'VertexProperty' must have a 'name'
> gV().hasLabel("VertexProperty").or(__.hasNot("name"), __.has("name",
> P.eq(""))).id()
> 6) Every 'VertexProperty' must have a 'type'
> g.V().hasLabel("VertexProperty").or(__.hasNot("type"), __.has("type",
> P.eq(""))).id()
> 7) Every 'EdgePropery' must have a 'name'
> g.V().hasLabel("EdgeProperty").or(__.hasNot("name"), __.has("name",
> P.eq(""))).id()
> 8) Every 'EdgeProperty' must have a 'type'
> g.V().hasLabel("EdgeProperty").or(__.hasNot("type"), __.has("type",
> P.eq(""))).id()
> 9) Every 'VertexProperty' must have a in 'properties' edge.
> g.V().hasLabel("VertexProperty").where(__.not(__.in("properties"))).id()
> 10) Every 'EdgeProperty' must have a in 'properties' edge.
> g.V().hasLabel("EdgeProperty").where(__.not(__.in("properties"))).id()
> ...
>
> This can be visualized as,
>
>
> 2: The model
>
> What follows is an example of TinkerPop's 'modern' graph specified as an
> instance of the above property graph meta model.
>
> public static Graph modernModel() {
> //import this from a base package
> enum GremlinDataType {
> STRING,
> INTEGER,
> DOUBLE,
> DATE,
> TIME
> //...
> }
>
> TinkerGraph modernModelGraph = TinkerGraph.open();
>
> Vertex person = modernModelGraph.addVertex(T.label, "VertexLabel",
> "label", "person");
> Vertex personNameVertexProperty = modernModelGraph.addVertex(T.label,
> "VertexProperty", "name", "name", "type", GremlinDataType.STRING.name());
> Vertex personAgeVertexProperty = modernModelGraph.addVertex(T.label,
> "VertexProperty", "name", "age", "type", GremlinDataType.INTEGER.name());
> person.addEdge("properties", personNameVertexProperty);
> person.addEdge("properties", personAgeVertexProperty);
>
> Vertex software = modernModelGraph.addVertex(T.label, "VertexLabel",
> "label", "software");
> Vertex softwareNameVertexProperty =
> modernModelGraph.addVertex(T.label, "VertexProperty", "name", "name", "type",
> GremlinDataType.STRING.name());
> Vertex softwareLangVertexProperty =
> modernModelGraph.addVertex(T.label, "VertexProperty", "name", "lang", "type",
> GremlinDataType.STRING.name());
> software.addEdge("properties", softwareNameVertexProperty);
> software.addEdge("properties", softwareLangVertexProperty);
>
> Vertex knows = modernModelGraph.addVertex(T.label, "EdgeLabel",
> "label", "knows");
> Vertex knowsWeightVertexProperty =
> modernModelGraph.addVertex(T.label, "EdgeProperty", "name", "weight", "type",
> GremlinDataType.INTEGER.name());
> knows.addEdge("properties", knowsWeightVertexProperty);
>
> Vertex created = modernModelGraph.addVertex(T.label, "EdgeLabel",
> "label", "created");
> Vertex createdWeightVertexProperty =
> modernModelGraph.addVertex(T.label, "EdgeProperty", "name", "weight", "type",
> GremlinDataType.INTEGER.name());
> created.addEdge("properties", createdWeightVertexProperty);
>
> person.addEdge("outEdge", knows);
> person.addEdge("outEdge", created);
> software.addEdge("inEdge", knows);
> software.addEdge("inEdge", created);
> return modernModelGraph;
> }
>
> The above gremlin constraints need to be executed against the
> 'modernModelGraph' to check for the correctness of the model. If the
> constraints pass we know that the model is indeed a valid Gremlin property
> graph model.
>
> We can certainly specify more constraints but the ones defined above passes
> on the 'modernModelGraph'.
>
> 3: The actual graph
>
> TinkerGraph modernGraph = TinkerFactory.createModern();
>
> And that is it.
>
> There are lots of details to complete, but first we need to see if there is
> any appetite for a modelling approach as I realize there is some academic
> abstract algebra work happening elsewhere. It seems to me to have a lower
> barrier to entry for the community to partake in the discussion of what
> constitutes a property graph model.
>
> Let me know if there are questions or criticisms.
>
> Thanks
> Pieter