简体   繁体   中英

How to find graph schema in Gremlin?

I wanna to find all node and edge properties in graph. How can I list node (or edge) properties that exist in graph?

for example if nodes has 3 non-reserved properties such as NAME, education, gender. I wanna a methods like

g.V().schema().toList();
// result: [ID, LABEL, NAME, GENDER, EDUCATION]

Gremlin itself has no notion of schema. This was a deliberate design choice as the capabilities and behavior around schema APIs is quite different from one graph system implementation to the next and forming an appropriate abstraction in Apache TinkerPop for that is quite difficult. In this way it is quite akin to TinkerPop 2.x's attempt to build a general index API, which ended up being too generic to be useful to anyone and had there been more complexity added, more that what was required for most cases. In the end, like indexing APIs, ideas for generalizing schema were left out for TinkerPop 3.x.

If you use a graph that allows for schema definition like JanusGraph or DSE Graph you should simply use the underlying Schema API of that graph system to get all of your schema values. If you aren't using that type of graph then you will need to do something along the lines of what has been offered in the other answers thus far and iterate through all of the vertices (or edges) and get the unique property keys. Here's my version:

gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().properties().key().dedup()
==>name
==>age
==>lang

The problem here is that to do this type of traversal, you will require a full graph scan, which will be problematic if you have a large graph. In those cases you will need to use an OLAP-based traversal with Spark or the like.

If all nodes have a same properties. we can find the properties of the first vertex and generalize it to all nodes:

TinkerGraph tg = TinkerGraph.open() ;
tg.io(IoCore.graphml()).readGraph("src\\main\\resources\\air-routes.graphml");
GraphTraversalSource g = tg.traversal();

g.V().propertyMap().select(Column.keys).next();
// result = {LinkedHashSet@1831}  size = 12
// 0 = "country"
// 1 = "code"
// 2 = "longest"
// 3 = "city"
// 4 = "elev"
// 5 = "icao"
// 6 = "lon"
// 7 = "type"
// 8 = "region"
// 9 = "runways"
// 10 = "lat"
// 11 = "desc"

but If there is no guaranty to each node has a same set of properties, I don't find any other solution instead of retrieving all properties in a Map List and find distinct property with java collection methods (outside Gremlin).

The last two lines in the JUnit Test Case might be closer to do what you want. see also:

https://github.com/BITPlan/com.bitplan.simplegraph/blob/master/simplegraph-core/src/test/java/com/bitplan/simplegraph/core/TestTinkerPop3.java

graph.traversal().V().next().properties()
    .forEachRemaining(prop -> System.out.println(String.format("%s=%s",
        prop.label(), prop.value().getClass().getSimpleName())));
graph.traversal().V().next().edges(Direction.OUT)
    .forEachRemaining(edge -> System.out.println(
        String.format("%s->%s", edge.label(), edge.outVertex().label())));

producing:

name=String
age=Integer
created->person
knows->person

JUnit Test Case

  @Test
  public void testSchema() {
    Graph graph = TinkerFactory.createModern();
    graph.traversal().V().next().properties()
        .forEachRemaining(prop -> System.out.println(String.format("%s=%s",
            prop.label(), prop.value().getClass().getSimpleName())));
    graph.traversal().V().next().edges(Direction.OUT)
        .forEachRemaining(edge -> System.out.println(
            String.format("%s->%s", edge.label(), edge.outVertex().label())));
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM