3

I faced this issue during a migration of gremlin queries from v2 to v3.

V2-way: inE().has(some condition).outV().map().toList()[0] will return an object. This is wrapped in transform{label: it./etc/} step.

V3-way, still WIP: inE().has(some condition).outV().fold() will return an array. This is wrapped in project(...).by(...) step.

V3 works fine, I just have to unwrap an item from the array manually. I wonder if there is a more sane approach (anyway, this feels like non-graph-friendly step).

Environment: JanusGraph, TinkerPop3+. For v2: Titan graph db and TinkerPop2+.

Update: V3 query sample

inE('edge1').
  has('cond1').outV(). // one vertex left
  project('items', 'count'). // pagination
    by(
      order().
        by('field1', decr).
          project('vertex_itself', 'vertex2', 'vertices3').
            by(identity()).
            by(outE('edge2').has('type', 'type1').limit(1).inV().fold()). // now this is empty array or single-element array, can we return element itself?
            by(inE('edge2').has('type', 'type2').outV().fold()).
          fold()).
    by(count())

Desired result shape:

[{
  items: [
    {vertex_itself: Object, vertex2: Object/null/empty, veroces3: Array},
    {}...
  ],
  cont: Number,
}]

Problem: vertex2 property is always an array, empty or single-element.
Expected: vertex2 to be object or null/empty.

Update 2: it turns out my query is not finished yet, it returns many object if there are no single element in has('cond1').outV() step, e.g. [{items, count}, {items, count}...]

amankkg
  • 4,503
  • 1
  • 19
  • 30
  • Why there is `fold()` steps in `project().by(...fold())`? If I remove them I get an error `The provided traverser does not map to a value` – amankkg Sep 20 '18 at 08:54
  • now I see that the question is very confusing, even initially given query is not working as described by myself. Let's close this one for now – amankkg Sep 21 '18 at 08:57

2 Answers2

3

I may not fully understand, but it sounds like from this:

inE().has(some condition).outV().fold()

you want to just grab the first vertex you come across. If that's right, then is there a reason to fold() at all? maybe just do:

inE().has(some condition).outV().limit(1)
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • 2
    good point, I'll add it like this `inE().has(some condition).limit(1).outV()`. But still, `limit` step will return array with single element. Is it possible to get element itself OR null, not an array? – amankkg Sep 20 '18 at 08:28
  • added question comment on `fold()` steps usage – amankkg Sep 20 '18 at 08:55
3

it looks like your main issue is getting a single item from the traversal.

you can do this with next(), which will retrieve the next element in the current traversal iteration:

inE().has(some condition).outV().next()

the iteratee's structure is, i think, implementation specific. e.g. in javascript, you can access the item with the value property:

const result = await inE().has(some condition).outV().next();
const item = result.value;
Eliran Malka
  • 15,821
  • 6
  • 77
  • 100