Fook
Fook

Reputation: 5550

The provided start does not map to a value

I have a traversal as follows:

g.V().hasLabel("demoUser")
.as("demoUser","socialProfile","followCount","requestCount")
.select("demoUser","socialProfile","followCount","postCount")
.by(__.valueMap())
.by(__.out("socialProfileOf").valueMap())
.by(__.in("followRequest").hasId(currentUserId).count())
.by(__.outE("postAuthorOf").count())

I'm trying to select a user vertex, their linked social profile vertex, and some other counts. The issue is that all users may not have a socialProfile edge. When this is the case the traversal fails with the following error:

The provided start does not map to a value: v[8280]->[TitanVertexStep(OUT,[socialProfileOf],vertex), PropertyMapStep(value)]

I did find this thread from the gremlin team. I tried wrapping the logic inside of .by() with a coalesce(), and also appending a .fold() to the end of the statement with no luck.

How do I make that selection optional? I want to select a socialProfile if one exists, but always select the demoUser.

Upvotes: 1

Views: 1258

Answers (1)

Daniel Kuppitz
Daniel Kuppitz

Reputation: 10904

coalesce is the right choice. Let's assume that persons in the modern graph have either one or no project associated with them:

gremlin> g.V().hasLabel("person").as("user","project").
           select("user","project").by("name").by(coalesce(out("created").values("name"),
                                                           constant("N/A")))
==>{user=marko, project=lop}
==>{user=vadas, project=N/A}
==>{user=josh, project=ripple}
==>{user=peter, project=lop}

Another way would be to completely exclude it from the result:

g.V().hasLabel("person").as("user","project").choose(out("created"),
    select("user","project").by("name").by(out("created").values("name")),
    select("user").by("name"))

But obviously this will only look good if each branch returns a map / selects more than 1 thing, otherwise you're going to have mixed result types.

Upvotes: 5

Related Questions