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