Very cool!

Btw, just added parameters to the  Cypher REST Plugin too, since
Andres pushed them into the core parser.
http://docs.neo4j.org/chunked/snapshot/cypher-plugin.html#rest-api-send-queries-with-parameters
which will mean the mode of submission is the same for Gremlin and
Cypher.

Cheers,

/peter neubauer

GTalk:      neubauer.peter
Skype       peter.neubauer
Phone       +46 704 106975
LinkedIn   http://www.linkedin.com/in/neubauer
Twitter      http://twitter.com/peterneubauer

http://www.neo4j.org               - Your high performance graph database.
http://startupbootcamp.org/    - Öresund - Innovation happens HERE.
http://www.thoughtmade.com - Scandinavia's coolest Bring-a-Thing party.



On Tue, Oct 4, 2011 at 7:25 AM, Tatham Oddie <[email protected]> wrote:
> Hi Marko,
>
> That's exactly what we're doing.
>
> In C# we translate the expression trees from the predicates into Groovy 
> lambdas we can send over the wire.
>
> The fluent methods all just return enumerables along the way so it's deferred 
> execution at the end.
>
> We use generics to pass the right type to the predicates:
>
>    IGremlinNodeEnumerable<TNode> Out<TNode>(string relationshipType, 
> Func<TNode, bool> predicate) {...}
>
> This allows usage like this, where 'p' is of type Program and you get Visual 
> Studio IntelliSense when you type p.Name:
>
>    var programs = graphClient.RootNode.Out<Program>(HasProgram.TypeKey, p => 
> p.Name == "foo");
>
> During the translation, all of the dynamic parts are quietly whisked away 
> into Gremlin parameters. The last example goes over the wire like this:
>
>    {
>        'script': 'g.v(p0).outE[[label:p1]].inV{it[p2].equalsIgnoreCase(p3)}',
>        'params': {
>            'p0': 0,
>            'p1': 'HAS_PROGRAM',
>            'p2': 'Name',
>            'p3': 'foo'
>        }
>    }
>
> Using the parameters a) saves Gremlin from having to parse the query again 
> and b) saves us from having to worry about escaping strings into Java format 
> (we just serialize to JSON instead).
>
> To make debugging easier, both GremlinNodeEnumerator and 
> GremlinRelationshipEnumerator expose a DebugQueryText property. This returns 
> an artificially expanded version of the query so that you can copy one string 
> from the watch window straight into the neo4j web console for query 
> debugging. (As opposed to the version of the query text with the param 
> markers.) This is just a dumb replacement of pN with '{value}' and thus not 
> guaranteed to be accurate, but it still helps.
>
> You'll also notice in this translation that p.Name=="foo" was translated to 
> {it[p2].equalsIgnoreCase(p3)}. By default, we perform case insensitive 
> comparisons on strings as that was more consistent with MS SQL (the data 
> source most .NET devs use as a baseline). Of course, there's an overload that 
> allows you to specify the case comparison mode. Our currently approach may or 
> may not be right for other projects, but time will tell.
>
> The only two places we really deviate from Gremlin are:
>
> - Instead of .count() we have .GremlinCount(). .NET already has a built in 
> Count method that spins through the enumerator and counts the number of 
> entries returned. Ultimately we will intercept this, but for now the simplest 
> option was just to use a different name that didn't clash.
>
> - Because we're in a statically typed language, we had to implement BackE and 
> BackV so that we could return a IGremlinRelationshipEnumerable or 
> IGremlinNodeEnumerable<TNode> respectively. We figured this would still be a 
> fairly obvious signature.
>
> There's definitely some expression tree gymnastics and generics craziness in 
> there to make all that happen, but it has been fun. :)
>
>
> -- Tatham
>
>
> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On 
> Behalf Of Marko Rodriguez
> Sent: Tuesday, 4 October 2011 3:21 AM
> To: Neo4j user discussions
> Subject: Re: [Neo4j] C# REST binding / wrapper
>
> Hey Romiko,
>
>> http://romikoderbynew.com/2011/07/30/neo4jclient-primer/
>
> That is really cool how you build a Gremlin expression in C# using a fluent 
> pattern and then, I suspect, transform it to the appropriate Gremlin string 
> representation for transport over the wire to Neo4j REST Server. Is that what 
> you are doing? If so, that is a neat way to build language bindings that are 
> not just server.eval("some.big.fat.string.all.old.skool.rdbms.style")?
>
> Finally, in a similar note, TinkerPop is generalizing Gremlin away from a 
> particular language implementation. We want to provide the "Gremlin-style" to 
> any JVM language, not just Groovy. We plan to have Gremlin_scala out in the 
> next release... E.g.:
>
>        gremlin-groovy: g.v(1).out('knows').name.filter{it == 'josh'}
>        gremlin-scala: g.v(1).out("knows").property("name").filter{_ == "josh"}
>
> There is an strong conceptual overlap to how you are doing your C# binding 
> and how Gremlin is becoming JVM language agnostic.... makes me think. :/
>
> Anywho, I like the work you did. Thank you for sharing, Marko.
>
> http://markorodriguez.com
> _______________________________________________
> Neo4j mailing list
> [email protected]
> https://lists.neo4j.org/mailman/listinfo/user
> _______________________________________________
> Neo4j mailing list
> [email protected]
> https://lists.neo4j.org/mailman/listinfo/user
>
_______________________________________________
Neo4j mailing list
[email protected]
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to