Search code examples
gremlintinkerpopgremlin-server

what is the best way to search with multi properties in gremlin


I want a path from vertex A,C,D,E,G,H,

I tired with following code

 g.V().hasLabel('a').repeat(out().simplePath()).until(hasLabel('h')).
     path().by(values('vehicle','time').fold()) 

my received output

[[10.00,8.30,v1,v2],[10.30,9.00,9.30,v1,v2,v3],[11.00,9.30,10.00,v1,v2,v3],[1
1.30,10.00,10.30,v1,v2,v3],[12.00,11.00,v1,v3],[12.30,11.30,v1,v3]]

expected output

[a:[10.00,v1],c:[11.00,v1],d:[11.30,v1],e:[12.00,v1],g:[12.30,v1],h:[1.00,v1]],[a:[8.30,v2],c:[9.00,v2],d:[9.30,v2],e:[10.00,v2],g:[11.00,v3],h:[11.30,v3]]

the following is a sample graph

    v1 = graph.addVertex(id,1,label,'a','vehicle','v1','time',10.00)
    v2 = graph.addVertex(id,2,label,'b','vehicle','v1','time',10.30)
    v3 = graph.addVertex(id,3,label,'c','vehicle','v1','time',11.00)
    v4 = graph.addVertex(id,4,label,'d','vehicle','v1','time',11.30)
    v5 = graph.addVertex(id,5,label,'e','vehicle','v1','time',12.00)
    v7 = graph.addVertex(id,7,label,'g','vehicle','v1','time',12.30)
    v8 = graph.addVertex(id,8,label,'h','vehicle','v1','time',1.00)

    v1.addEdge('traveles',v3)
    v3.addEdge('traveles',v4)
    v4.addEdge('traveles',v5)
    v5.addEdge('traveles',v7)
    v7.addEdge('traveles',v8)

 g.V(1).property(list,'vehicle','v2').property(list,'time',8.30)

  g.V(3).property(list,'vehicle','v2').property(list,'time',9.00).property(list,'vehicle','v3').property(list,'time',9.30)

    g.V(4).property(list,'vehicle','v2').property(list,'time',9.30).property(list,'vehicle','v3').property(list,'time',10.00)

    g.V(5).property(list,'vehicle','v2').property(list,'time',10.00).property(list,'vehicle','v3').property(list,'time',10.30)

    g.V(7).property(list,'vehicle','v3').property(list,'time',11.00)

  g.V(8).property(list,'vehicle','v3').property(list,'time',11.30)

can anyone help me please


Solution

  • If your property has multiple values then the values step will return them all. Assuming you have two values you can select one or the other using limit or tail.

    gremlin> g.addV('test').property(list,'x',1).property(list,'x',2)
    ==>v[61316]
    gremlin> g.V(61316).values('x')
    ==>1
    ==>2
    gremlin> g.V(61316).values('x').tail(1)
    ==>2
    gremlin> g.V(61316).values('x').limit(1)
    ==>1 
    

    If you have more than 2 values and you need to select one from the middle of a list or set you can use the range step to select that value.

    gremlin> g.V(61316).property(list,'x',5)
    ==>v[61316]
    gremlin> g.V(61316).values('x')
    ==>1
    ==>2
    ==>5
    gremlin> g.V(61316).values('x').range(1,2)
    ==>2  
    

    All of this said if you could edit your question with some sample data it would help give a better answer as it seems your data model has lots of values for each property so Gremlin is doing what you are asking it to.

    Also, in your example you are finding vertices by their label and not testing the values at all. You can test a multi-property just as you would a single property

    gremlin> g.V().has('x',2)
    ==>v[61316
    

    EDITED to add:

    Using these techniques, you could change your path statement to something like this:

    path().
       by(union(label,
                values('time').limit(1),
                values('vehicle').limit(1)).fold())