F # - cypher request with multiple return values

Given this request ( here )

let pAfollowers = client.Cypher .Match("n<-[:follows]-e") .Where(fun n -> n.Twitter = "tA") .Return<Person>("e") .Results .Select(fun x -> x.Name) 

I would like to customize it and return to it several values ​​packed together. Not sure what the type looks like:

 let pAfollowers = client.Cypher .Match("n<-[r:follows]-e") .Where(fun n -> n.Twitter = "tA") .Return<???>("n, r, e") 

Secondly, I was wondering if it is possible to have a return statement after CreateUnique . I am trying to configure this query:

 let knows target (details : Knows) source = client.Cypher .Match("(s:Person)", "(t:Person)") .Where(fun s -> s.Twitter = source.Twitter) .AndWhere(fun t -> t.Twitter = target.Twitter) .CreateUnique("s-[:knows {knowsData}]->t") .WithParam("knowsData", details) .ExecuteWithoutResults() 

to return s , t and details .

+6
source share
2 answers

Good, good news / bad news - although in practice, good is tempered badly: (

Ok first:

You can return after CreateUnique, something like:

 .CreateUnique("s-[:Knows {knowsData}]-t") .WithParam("knowsData", details) .Returns<???>( "s,t" ) .Results; 

Bad news:

The bad news is that you probably can't do this in F #. Neo4jClient requires that you use either object initializers or anonymous data types so that you can try something like:

 type FollowingResults = { Follower : Person; Followed : Person;} let createExpression quotationExpression = LeafExpressionConverter.QuotationToLambdaExpression quotationExpression let pAfollowers = client.Cypher .Match("n<-[:follows]-e") .Where(fun n -> n.Twitter = "tA") .Return(createExpression <@ Func<ICypherResultItem, ICypherResultItem, FollowingResults>(fun (e : Cypher.ICypherResultItem) (n : Cypher.ICypherResultItem) -> {Follower = e.As<Person>(); Followed = n.As<Person>()}) @>) .Results .Select(fun x -> x) for follower in pAfollowers do printfn "%s followed %s" follower.Follower.Name follower.Followed.Name 

There will be no problem for the F # compiler. However, Neo4jClient throws an Argument exception with the following message:

The expression must be constructed as an object initializer (for example: n => new MyResultType {Foo = n.Bar}), an anonymous type initializer (for example: n => new {Foo = n.Bar}), a method call (for example: n = > n.Count ()) or member access element (for example: n => n.As (). Bar). You cannot provide blocks of code (for example: n => {var a = n + 1; return a;}) or use constructors with arguments (for example: n => new Foo (n)).

The problem is that F # does not have object initializers or anonymous types, you can argue with F # materials for ages and will not go anywhere, since C # does not recognize F # initialization.

+3
source

I have some good news for both. This code will be compiled simply using tuples and can be used with a modified Neo4jClient that supports F # Tuples: https://github.com/n074v41l4bl34u/Neo4jClient The solution is based on: https://fsharppowerpack.codeplex.com/workitem/4572

  let knows target (details : Knows) source = client.Cypher .Match("(s:Person)", "(t:Person)") .Where(fun s -> s.Twitter = source.Twitter) .AndWhere(fun t -> t.Twitter = target.Twitter) .CreateUnique("s-[:knows {knowsData}]->t") .WithParam("knowsData", details) .Return(fun st -> s.As<Person>(),t.As<Person>()) let pAfollowers = client.Cypher .Match("n<-[:follows]-e") .Where(fun n -> n.Twitter = "tA") .Return(fun (e : Cypher.ICypherResultItem) n -> e.As<Person>().Name,n.As<Person>().Name) 

Type annotations on '(e: Cypher.ICypherResultItem)' may not be present when using more than one argument in fun .

However, when using one argument, this eliminates the ugly syntax createExpression <@Func (...) @>) . Learn more about why look at the bottom of this page: https://gist.github.com/cskardon/8300420

+1
source

All Articles