What would be the interpretation if multiple arguments to mutator steps are
iterators?  Without guaranteed order, the "zip" interpretation is
meaningless.  A cross-product interpretation would be robust, but not
necessarily useful unless coupled with `where` (like a relational join).


On Wed, Aug 26, 2015 at 8:15 AM, Marko Rodriguez <[email protected]>
wrote:

> Hey,
>
> Here is the final question I have. If the "x" is an iterable, should we
> iterate it or does "x" have to reference a vertex. For instance.
>
>
> g.V.aggregate('x').as('a').select('x').unfold().addE("knows").to('a')
>
> OR
>
>         g.V.aggregate('x').as('a').addE("knows").to('x')
>
> While the latter looks enticing, I don't know if its a good thing. Trying
> to think through the ramifications… However, a better example of why
> iterable/iterator support would be smart:
>
>         g.V.as
> ('a').out('knows').as('b').addE('friendsParent').from('a').to(select('b').out('parent'))
>
> Given that the to() is a traversal, it is an iterator/iterable.
>
> Any thoughts on the matter beyond just "that would be nice" based on how
> this plays within the larger scope of the language itself. For instance, no
> step-modulators support traversal beyond .next(). E.g.
>
>         g.V.groupCount().by(out('knows').values('name'))
>
> Will just group by the first person they knows name. Not all names. To do
> all names, its:
>
>         g.V.groupCount().by(out('knows').values('name').fold())
>
> If to() and from() supported iterable/iterator, these would differ from
> the rest of the language. You may so, "thats fine." Well, then what about
> properties, shouldn't they then support iterable/iterator unfolding as you
> may have a "zip"-style.
>
>         g.V.as
> ('a').out('knows').as('b').addE('friendsParent').from('a').to(select('b').out('parent')).property('weight',select('a').out('knows').values('weight'))
>
> …….but now we are just getting crazy and complex. I would prefer to NOT
> support to()/from() being "iterable/iterator" compliant, but it sure is
> damn convenient……….
>
> Thoughts?,
> Marko.
>
> http://markorodriguez.com
>
> On Aug 26, 2015, at 8:06 AM, Matt Frantz <[email protected]>
> wrote:
>
> > Now all we need is the mid-traversal V/E:
> > https://issues.apache.org/jira/browse/TINKERPOP3-762
> >
> > Then, the reasoning API will be fully operational.
> >
> > On Tue, Aug 25, 2015 at 6:58 PM, Marko Rodriguez <[email protected]>
> > wrote:
> >
> >> Hi,
> >>
> >> In theory, yes. The problem is that we don't have a g.inject() off
> >> GraphTraversalSource. If you use an anonymous traversal, there is no
> graph
> >> and thus, AddXXXStep doesn't know the graph to add things too. Thus, we
> >> need something like:
> >>
> >> g.inject('alice', 'bob', 'charlie').as('name').
> >>  addV('person').property('name', select('name'))
> >>
> >> NOTE: In your emails and in your JIRA tickets you tend to word wrap on
> the
> >> "." and thus, you can't copy/paste your examples into the console. For
> >> instance:
> >>
> >> BAD:
> >>
> >> __('alice', 'bob', 'charlie').as('name')
> >> .addV('person').property('name', select('name'))
> >>
> >> GOOD:
> >>
> >> __('alice', 'bob', 'charlie').as('name').
> >> addV('person').property('name', select('name'))
> >>
> >> Easy to add… In fact, probably will just add that now. If people have a
> >> better idea than g.inject(…), please advise.
> >>
> >> <coding….>
> >>
> >> Okay. Added to mutating_traverser/ branch (will push once integration
> >> tests complete). Here is your example:
> >>
> >> gremlin> g.inject('alice', 'bob',
> >> 'charlie').as('a').addV('person').property('name', select('a'))
> >> ==>v[0]
> >> ==>v[2]
> >> ==>v[4]
> >> gremlin> g.V().valueMap()
> >> ==>{name=[alice]}
> >> ==>{name=[bob]}
> >> ==>{name=[charlie]}
> >>
> >> Pretty freakin' sweet.
> >>
> >> Thanks,
> >> Marko.
> >>
> >> http://markorodriguez.com
> >>
> >> On Aug 25, 2015, at 5:36 PM, Matt Frantz <[email protected]>
> >> wrote:
> >>
> >>> If you're starting from scratch (empty graph), would you use an
> anonymous
> >>> traversal to add elements?
> >>>
> >>> __('alice', 'bob', 'charlie').as('name')
> >>> .addV('person').property('name', select('name'))
> >>>
> >>>
> >>> On Tue, Aug 25, 2015 at 3:31 PM, Marko Rodriguez <[email protected]
> >
> >>> wrote:
> >>>
> >>>> Hello,
> >>>>
> >>>> The mutating_traverser/  branch has the implementation of the proposal
> >>>> discussed in the previous email.
> >>>>
> >>>> https://github.com/apache/incubator-tinkerpop/tree/mutating_traverser
> >>>> Here is the key change to the GraphTraversal DSL:
> >>>>
> >>>>
> >>
> https://github.com/apache/incubator-tinkerpop/blob/mutating_traverser/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java#L640-L726
> >>>>
> >>>> Here is a Gremlin Console session so people can see how nice the new
> >> model
> >>>> is:
> >>>>
> >>>> gremlin> g = TinkerFactory.createModern().traversal()
> >>>> ==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
> >>>> gremlin> g.V().as('a').out('created').addE('createdBy').to('a')
> >>>> ==>e[12][3-createdBy->1]
> >>>> ==>e[13][5-createdBy->4]
> >>>> ==>e[14][3-createdBy->4]
> >>>> ==>e[15][3-createdBy->6]
> >>>> gremlin> g.V().as('a').outE('created').as('b').inV().
> >>>>
> >>>>
> >>
> addE('createdBy').to('a').property('weight',select('b').values('weight')).
> >>>>          valueMap()
> >>>> ==>[weight:0.4]
> >>>> ==>[weight:1.0]
> >>>> ==>[weight:0.4]
> >>>> ==>[weight:0.2]
> >>>> gremlin> g.V().as('a').addE('pet').to(addV('animal').property('name',
> >>>> select('a').by('name').map{it.get() + "'s pet"}))
> >>>> ==>e[26][1-pet->24]
> >>>> ==>e[29][2-pet->27]
> >>>> ==>e[32][3-pet->30]
> >>>> ==>e[35][4-pet->33]
> >>>> ==>e[38][5-pet->36]
> >>>> ==>e[41][6-pet->39]
> >>>> gremlin> g.V().hasLabel('animal').valueMap()
> >>>> ==>[name:[josh's pet]]
> >>>> ==>[name:[ripple's pet]]
> >>>> ==>[name:[peter's pet]]
> >>>> ==>[name:[marko's pet]]
> >>>> ==>[name:[vadas's pet]]
> >>>> ==>[name:[lop's pet]]
> >>>>
> >>>> Pretty wicked, eh?
> >>>>
> >>>> Note that that the old Mutation methods still exist (though they are
> >>>> @Deprecated) and they simply call those new AddXXXStep steps
> >> accordingly.
> >>>> The only thing left to do is update the documentation.
> >>>>
> >>>> Please review the work and if you are happy, I can merge master/ and
> >> then
> >>>> update the docs.
> >>>>
> >>>> Thanks,
> >>>> Marko.
> >>>>
> >>>> http://markorodriguez.com
> >>>>
> >>>> On Aug 25, 2015, at 9:44 AM, Marko Rodriguez <[email protected]>
> >> wrote:
> >>>>
> >>>>> Hello,
> >>>>>
> >>>>> TinkerPop3 made a stance against TinkerPop2 and said: "there are no
> >> such
> >>>> thing as lambdas --- lambdas are traversals!"
> >>>>>
> >>>>> Next --- the mutation steps in TinkerPop3 are sorta clunky and ugly.
> >>>> Moreover, people want mid-traversal parameterization. That is,
> something
> >>>> like:
> >>>>>
> >>>>> addV(T.label, select("a").label())
> >>>>>
> >>>>> This got us to thinking. EVERYTHING IS A TRAVERSAL. There are no such
> >>>> things a primitives. Gremlin works with only one type of object --
> >>>> Traversal. While this sounds crazy, its actual realization into
> >> TinkerPop
> >>>> 3.1.0 would be simple. However, our mutation steps as we have them
> now,
> >>>> would be @Deprecated. :( Everything else would stay the same. :)
> >> Ignoring
> >>>> the general theory of "EVERYTHING IS A TRAVERSAL," lets look at a
> >> practical
> >>>> day one ramification.
> >>>>>
> >>>>> Here is the thread of thought:
> >>>>>     https://issues.apache.org/jira/browse/TINKERPOP3-799
> >>>>>
> >>>>> Here is a break down of what of what we propose for TinkerPop 3.1.0.
> >>>>>
> >>>>> addV("person").property("name","marko")
> >>>>> addV("person").property("name",select("a").by("name"))
> >>>>> addE("likes").from("a").to("b")
> >>>>>
> >>>>
> >>
> addE("knows").from(select("a").in("likes")).to(select("b").in("employees"))
> >>>>> addE("likes").from(select("a").in("likes")).to("a")
> >>>>>
> >>>>
> >>
> addE("likes").from("a").to("b").property(select("a").by("key"),select("a").by("value"))
> >>>>> out(select("a").label())
> >>>>>
> >>>>> In short, every step's parameters can be traversals which are
> evaluated
> >>>> at runtime. Thus, the query is parameterized by the traverser.
> >> Psychedelic.
> >>>>>
> >>>>> For now, I'm not so interested in out(select("a").label()) as much as
> >> in
> >>>> cleaning up the mutation steps (property(), addV(), addE()) as this is
> >>>> where people seem to want this type of runtime parameterization and
> >> where
> >>>> our current GraphTraversal API is weak.
> >>>>>
> >>>>> If anyone has any thoughts on the matter, please espouse them.
> >>>>>
> >>>>> *** Note for vendors. I know Titan, so I will show how this is crazy
> >> for
> >>>> Titan and hopefully other vendors see the complexity. When a user does
> >>>> out(select("a").label()), then Titan's vertex-centric index step will
> >> NOT
> >>>> have the edge label at compile-time, but will have to compute for each
> >> and
> >>>> every traverser. I have already created a very nice object called
> >>>> "Parameters" which makes this easy, but still…….. This is also why I
> >> just
> >>>> want to focus on the mutation steps for now as those are not vendor
> >>>> optimized (as far as I know) and it provides us the most bang for our
> >> buck.
> >>>>>
> >>>>> Thanks,
> >>>>> Marko.
> >>>>>
> >>>>> http://markorodriguez.com
> >>>>>
> >>>>
> >>>>
> >>
> >>
>
>

Reply via email to