Shubham Yadav
Shubham Yadav

Reputation: 591

Gremlin Python: unhashable type: 'dict' while using groupCount on edges

I'm trying to calculate edge-betweenness. The query works fine on gremlin console but it doesn't work in gremlin-python.

g.V().as_("v").
  repeat(identity().as_("src").
         bothE().as_("e").
         bothV().as_("v").
         where(neq("src")).
         simplePath()).
    emit().
  filter(project("x","y","z").
           by(select(first, "v")).
           by(select(last, "v")).
           by(select("v").count(local)).as_("triple").
         coalesce(select("x","y").as_("a").
                  select("triples").unfold().as_("t").
                  select("x","y").
                  where(eq("a")).
                  select("t"),
                  store("triples")).
         select("z").as_("length").
         select("triple").
         select("z").
         where(eq("length"))).
   select('e').
   unfold().
   groupCount()

The error is: TypeError: unhashable type: 'dict'

If I change it to vertex-betweenness, then it works just fine. The problem I feel is how an edge is retrieved in python, it's a map. When I do group count it also creates a map which has it's key as the edge and value as the count. In python a key cannot be a map itself and thus throws this error.

How can this be fixed ? Also please explain how to use select(all, 'e') in gremlin-python.

Upvotes: 1

Views: 508

Answers (1)

stephen mallette
stephen mallette

Reputation: 46226

You've run into one of the limitations of gremlinpython in that Gremlin can return dict values that can't exist in Python. You will need to convert those keys to something that can exist as a key in Python while maintaining the information the key contains. I don't have a sample of your data or the output but I've contrived the following as a demonstration:

gremlin> g.V().both().elementMap().groupCount().unfold()
==>{id=5, label=software, name=ripple, lang=java}=1
==>{id=2, label=person, name=vadas, age=27}=1
==>{id=4, label=person, name=josh, age=32}=3
==>{id=3, label=software, name=lop, lang=java}=3
==>{id=1, label=person, name=marko, age=29}=3
==>{id=6, label=person, name=peter, age=35}=1

With a dict as the key this won't work in python and we'd get the same error as you're getting now. There are many options available for reforming this result to something python can consume, but here's a straightforward one just to get you thinking about what you might do:

gremlin> g.V().both().elementMap().groupCount().unfold().map(union(select(keys),select(values)).fold())
==>[[id:5,label:software,name:ripple,lang:java],1]
==>[[id:2,label:person,name:vadas,age:27],1]
==>[[id:4,label:person,name:josh,age:32],3]
==>[[id:3,label:software,name:lop,lang:java],3]
==>[[id:1,label:person,name:marko,age:29],3]
==>[[id:6,label:person,name:peter,age:35],1]

In the above, I deconstruct the dict into a list of pairs. Now you know on the client side that each result is one entry in the server side dict where the first value in the pair is the key and the second is the value.

Upvotes: 1

Related Questions