I like this new API. It is a tiny first step towards making the Java API a
little more DSL-like (1% of the way to the current scala and ruby API's :-)

My vote is actually for the includes() approach only because *and* is such a
widely used keyword. However, a quick test in Ruby showed that while
include() and 'and' are used, they can be overridden, and I believe using
either in the Java API will not affect their use in the Ruby API.

But to be careful, I'd still lean towards the safer includes() option.

And, this is Java, after all. Verbosity is expected ;-)

(I also noticed that reading the examples with and() correctly indicates
that the order of definition is irrelevant, while includes() almost implies
that the first relationship type has some kind of precedence. Could it?)

On Wed, Jun 23, 2010 at 6:01 PM, Alex Averbuch <alex.averb...@gmail.com>wrote:

> Hi,
> Personally I'd prefer and/not.
> It's intuitive to any programmer and has the bonus of being much shorter,
> so
> long complex expansions will appear less messy in practice.
>
> On Wed, Jun 23, 2010 at 5:45 PM, Tobias Ivarsson <
> tobias.ivars...@neotechnology.com> wrote:
>
> > Did anyone have an opinion on what to call the methods on the Expansion
> > interface that specify which types to expand.
> >
> > Alternative 1)
> > Expansion<T> and( RelationshipType type );
> > Expansion<T> and( RelationshipType type, Direction direction );
> > Expansion<T> not( RelationshipType type );
> >
> > Examples:
> > for (Node node : startNode.expand( KNOWS )
> >                          .and( LIKES )
> >                          .and( LOVES ) ) {
> >   doSomethingWith(node);
> > }
> >
> > Expansion<Relationship> expansion = startNode.expand( KNOWS );
> > expansion = expansion.and( LIKES );
> > expansion = expansion.and( LOVES );
> >
> >
> > Alternative 2)
> > Expansion<T> including( RelationshipType type );
> > Expansion<T> including( RelationshipType type, Direction direction );
> > Expansion<T> excluding( RelationshipType type );
> >
> > Examples:
> > for (Node node : startNode.expand( KNOWS )
> >                          .including( LIKES )
> >                          .including( LOVES ) ) {
> >   doSomethingWith(node);
> > }
> >
> > Expansion<Relationship> expansion = startNode.expand( KNOWS );
> > expansion = expansion.including( LIKES );
> > expansion = expansion.including( LOVES );
> >
> >
> > Cheers,
> > Tobias
> >
> > On Wed, Jun 23, 2010 at 11:14 AM, Tobias Ivarsson <
> > tobias.ivars...@neotechnology.com> wrote:
> >
> > > Hi Neo4j enthusiasts!
> > >
> > > Yesterday I committed an API that Mattias and I have been working on
> for
> > a
> > > few days. It comes in the form of two new interfaces Expander and
> > Expansion
> > > (in the org.neo4j.graphdb package), and four new methods in the Node
> > > interface (method names starting with "expand").
> > >
> > > The two main problems this API solves are:
> > > 1. Adds a clean way for getting related nodes from a source node.
> > > 2. Adds a type safe way for declaratively specifying any combination of
> > > RelationshipTypes and Directions to expand.
> > >
> > > This replaces what was actually an anti-pattern, but something we saw
> > > people doing a lot: using a depth-one traversal to get the nodes
> related
> > to
> > > a node, without needing to bother with the Relationship interface.
> > Example:
> > >
> > > // The most convenient way to write it in the past:
> > > Node source = ...
> > > Traverser traverser = source.traverse(
> > >     Traverser.Order.DEPTH_FIRST,
> > >     new StopAtDepth( 1 ),
> > >     ReturnableEvaluator.ALL_BUT_START_NODE,
> > >     TYPE_ONE, Direction.INCOMING,
> > >     TYPE_TWO, Direction.OUTGOING);
> > > for (Node related : traverser) {
> > >     doSomethingWith( related );
> > > }
> > >
> > > // The previously recommended (and bloated) way of doing it:
> > > Node source = ...
> > > for (Relationship rel : source.getRelationships( TYPE_ONE, TYPE_TWO ))
> {
> > >     Node related;
> > >     if (rel.isType(TYPE_ONE)) {
> > >         related = rel.getStartNode();
> > >         if (related.equals(source)) continue; // we only want INCOMING
> > > TYPE_ONE
> > >     } else if (rel.isType(TYPE_TWO)) {
> > >         related = rel.getEndNode();
> > >         if (related.equals(source)) continue; // we only want OUTGOING
> > > TYPE_TWO
> > >     } else {
> > >         continue; // should never happen, but makes javac know that
> > related
> > > is != null
> > >     }
> > >     doSomethingWith( related );
> > > }
> > >
> > > // With the new API:
> > > Node source = ...
> > > for (Node related : source.expand( TYPE_ONE, Direction.INCOMING )
> > >                           .add( TYPE_TWO, Direction.OUTGOING ).nodes())
> {
> > >     doSomethingWith( related );
> > > }
> > >
> > > The return type of the Node.expand(...)-methods are the new Expansion
> > type,
> > > it defaults to expanding to Relationship, but the
> > Expansion.nodes()-method
> > > makes it expand to Node. It also contains the add()-methods seen above
> > for
> > > specifying RelationshipTypes to include in the expansion. The spelling
> of
> > > this method isn't perfectly decided yet, we are choosing between "add",
> > > "and" and "include", we want something that reads nicely in the code,
> but
> > > doesn't conflict with keywords in other JVM-languages ("and" is a
> keyword
> > in
> > > Python, and I think "include" means something special in Ruby). There
> is
> > > also an Expansion.exlude(RelationshipType)-method for use together with
> > the
> > > Node.expandAll().
> > >
> > > The Expansion is backed by the newly added companion interface
> Expander.
> > > This is an extension of RelationshipExpander that adds builder
> > capabilities.
> > > It turns the functionality of the DefultExpander implementation class
> > (now
> > > removed) into an interface in the API. RelationshipExpander is still
> > around
> > > as a single method interface, which is useful for when you want to
> > implement
> > > your own expansion logic.
> > >
> > > This API is added to trunk so that we can get feedback from everyone
> who
> > > use the snapshot builds of Neo4j, if the response to this API
> > > isn't positive, it will probably be removed before the release of 1.1,
> so
> > > please submit comments in this thread on what you think about this API.
> > >
> > > Happy Hacking,
> > > --
> > > Tobias Ivarsson <tobias.ivars...@neotechnology.com>
> > > Hacker, Neo Technology
> > > www.neotechnology.com
> > > Cellphone: +46 706 534857
> > >
> >
> >
> >
> > --
> > Tobias Ivarsson <tobias.ivars...@neotechnology.com>
> > Hacker, Neo Technology
> > www.neotechnology.com
> > Cellphone: +46 706 534857
> > _______________________________________________
> > Neo4j mailing list
> > User@lists.neo4j.org
> > https://lists.neo4j.org/mailman/listinfo/user
> >
> _______________________________________________
> Neo4j mailing list
> User@lists.neo4j.org
> https://lists.neo4j.org/mailman/listinfo/user
>
_______________________________________________
Neo4j mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to