Node.ByIndexLookup and Where clause throwing exception - neo4jclient

I am trying to understand as to why the neo4jClient throws an exception, hope someone here could help me better understand whats going on.
first of all the following code works!!
qry = qry.Start(new
{
city = Node.ByIndexLookup(model.City.IndexName, "Label", data.RegistredAddress.City),
state = Node.ByIndexLookup(model.State.IndexName, "Label", data.RegistredAddress.State),
country = Node.ByIndexLookup(model.Country.IndexName, "Label", data.RegistredAddress.Country),
});
qry = qry.Match("(city)-[:BELONGS_TO_STATE]->(state)-[:BELONGS_TO_COUNTRY]-(country)").Return<Node<model.City>>("city");
but when I replace it with a different construct as below, it throws an exception
qry = qry.Start(new
{
city = Node.ByIndexLookup(model.City.IndexName, "Label", data.RegistredAddress.City),
});
qry = qry.Match("(city)-[:BELONGS_TO_STATE]->(state)-[:BELONGS_TO_COUNTRY]-(country)");
qry = qry.Where<model.State>(state => state.Label == data.RegistredAddress.State);
qry = qry.AndWhere<model.Country>(country => country.Label == data.RegistredAddress.Country);
var finalQry = qry.Return<Node<model.City>>("city");
I get an exception at the line where its trying to add a Where clause.
System.NotSupportedException: Unhandled node type MemberAccess in MemberExpression: value
detail of the stack trace is as follows
Neo4jClient.Cypher.CypherWhereExpressionVisitor.VisitMember(MemberExpression node) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherWhereExpressionVisitor.cs: line 145
System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Neo4jClient.Cypher.CypherWhereExpressionVisitor.VisitBinary(BinaryExpression node) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherWhereExpressionVisitor.cs: line 65
System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node)
System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Neo4jClient.Cypher.CypherWhereExpressionBuilder.BuildText(LambdaExpression expression, Func2 createParameterCallback) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherWhereExpressionBuilder.cs: line 15
Neo4jClient.Cypher.CypherFluentQuery.<>c__DisplayClassd.<Where>b__c(QueryWriter w) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherFluentQueryWhere.cs: line 11
Neo4jClient.Cypher.CypherFluentQuery.Mutate(Action1 callback) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherFluentQuery.cs: line 40
Neo4jClient.Cypher.CypherFluentQuery.Where(LambdaExpression expression) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherFluentQueryWhere.cs: line 10
Neo4jClient.Cypher.CypherFluentQuery.Where[T1](Expression1 expression) in c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\Cypher\CypherFluentQueryWhere.cs: line 34
Just curious to know what is the difference here & which of the 2 approach is a preferred way to query for performance reasons when boath works.
Regards
Kiran

OK, I have a solution that will get the code working, but to get it to work as you currently have it you'll need to put in a feature request / bug report at the Neo4jClient Issues Page. Issue 151 has been raised.
First, the solution:
You need to take the RegisteredAddress part of your data object and put it into another object, so:
var registeredAddress = data.RegisteredAddress;
then use that in your query:
var qry = qry.Where((model.State state) => state.Label == registeredAddress.State);
This will work and give you the results you want / need.
The reason:
Neo4jClient takes your lambda expression and parses it internally using an ExpressionVisitor based class. This at the moment will only go one deep in terms of looking for 'constant' expressions (i.e. actual values). Because data.RegisteredAddress.State is 2 expressions deep, it can't find the constant expression and such can't use it in the query.
Performance
I don't know for certain, but I would have thought the latter approach was fastest as traversal in neo4j is lightning fast, and you've only done one index lookup. There's probably not a whole lot in it to be honest...

Related

F#: How to examine content in a n-tuple and return true or false?

Consider this F# code:
let isSalary employee =
let (fName,lName,Occupation,Department,SalaryType,
HoursPerWeek, AnnualSalary, HourlyWage
) = employee
SalaryType = "Salary"
if(employee.SalaryType = SalaryType) then
true
else
false
Im getting errors in here, any fixes to it?
First things first, please post error messages and a much more specific question. Thanks! But luckily, I can about deduce the error messages from this problem.
Next, if you want to mutate SalaryType after you've deconstructed your employee 8-tuple, you should write using the mutable keyword:
let mutable (fName, lName, Occupation, Department, SalaryType,
HoursPerWeek, AnnualSalary, HourlyWage) = employee
But you shouldn't. This is explained further below.
Next problem: there is no dot notation (no tuple.member) for accessing members of a tuple. It's only possible through deconstruction. So you can't employee.SalaryType.
Here's what looks to be the crux of the problem, and it's a mistake I made many times when I was learning functional programming, and it's a difficult paradigm shift to adapt to. You should not be attempting to mutate data, or in this case, variables. Variables, or values as they are called in F#, shouldn't change, as a broad rule. Functions should be pure.
What this means is that any parameters you pass into a function should not change after leaving the function. The parameter employee should be the same after you return to the calling scope.
There's a few syntactical errors you've made that make it pretty much impossible for me to deduce what you're trying to do in the first place. Please include this in the question.
Also, one last nitpick. As you know, the last expression in an F# function is it's return value. Instead of using an if statement, just return the condition you're testing, like this:
let ...
...
employee.SalaryType = SalaryType <- but remember, you can't use dot notation on tuples; this is just an example
Please read more on
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/

Can I Use Multiple Properties in a StructuredFormatDisplayAttribute?

I'm playing around with StructuredFormatDisplay and I assumed I could use multiple properties for the Value, but it seems that is not the case. This question (and accepted answer) talk about customizing in general, but the examples given only use a single property. MSDN is not helpful when it comes to usage of this attribute.
Here's my example:
[<StructuredFormatDisplay("My name is {First} {Last}")>]
type Person = {First:string; Last:string}
If I then try this:
let johnDoe = {First="John"; Last="Doe"}
I end up with this error:
<StructuredFormatDisplay exception: Method 'FSI_0038+Person.First}
{Last' not found.>
The error seems to hint at it only capturing the first property mentioned in my Value but it's hard for me to say that with any confidence.
I have figured out I can work around this by declaring my type like this:
[<StructuredFormatDisplay("My name is {Combined}")>]
type Person = {First:string; Last:string} with
member this.Combined = this.First + " " + this.Last
But I was wondering if anyone could explain why I can't use more than one property, or if you can, what syntax I'm missing.
I did some digging in the source and found this comment:
In this version of F# the only valid values are of the form PreText
{PropertyName} PostText
But I can't find where that limitation is actually implemented, so perhaps someone more familiar with the code base could simply point me to where this limitation is implemented and I'd admit defeat.
The relevant code from the F# repository is in the file sformat.fs, around line 868. Omitting lots of details and some error handling, it looks something like this:
let p1 = txt.IndexOf ("{", StringComparison.Ordinal)
let p2 = txt.LastIndexOf ("}", StringComparison.Ordinal)
if p1 < 0 || p2 < 0 || p1+1 >= p2 then
None
else
let preText = if p1 <= 0 then "" else txt.[0..p1-1]
let postText = if p2+1 >= txt.Length then "" else txt.[p2+1..]
let prop = txt.[p1+1..p2-1]
match catchExn (fun () -> getProperty x prop) with
| Choice2Of2 e ->
Some (wordL ("<StructuredFormatDisplay exception: " + e.Message + ">"))
| Choice1Of2 alternativeObj ->
let alternativeObjL =
match alternativeObj with
| :? string as s -> sepL s
| _ -> sameObjL (depthLim-1) Precedence.BracketIfTuple alternativeObj
countNodes 0 // 0 means we do not count the preText and postText
Some (leftL preText ^^ alternativeObjL ^^ rightL postText)
So, you can easily see that this looks for the first { and the last }, and then picks the text between them. So for foo {A} {B} bar, it extracts the text A} {B.
This does sound like a silly limitation and also one that would not be that hard to improve. So, feel free to open an issue on the F# GitHub page and consider sending a pull request!
Just to put a bow on this, I did submit a PR to add this capability and yesterday it was accepted and pulled into the 4.0 branch.
So starting with F# 4.0, you'll be able to use multiple properties in a StructuredFormatDisplay attribute, with the only downside that all curly braces you wish to use in the message will now need to be escaped by a leading \ (e.g. "I love \{ braces").
I rewrote the offending method to support recursion and switched to using a regular expression to detect property references. It seems to work pretty well, although it isn't the prettiest code I've ever written.

Extending Query Expressions

Are there any documents or examples out there on how one can extend/add new keywords to query expressions? Is this even possible?
For example, I'd like to add a lead/lag operator.
In addition to the query builder for the Rx Framework mentioned by #pad, there is also a talk by Wonseok Chae from the F# team about Computation Expressions that includes query expressions. I'm not sure if the meeting was recorded, but there are very detailed slides with a cool example on query syntax for generating .NET IL code.
The source code of the standard F# query builder is probably the best resource for finding out what types of operations are supported and how to annotate them with attributes.
The key attributes that you'll probably need are demonstrated by the where clause:
[<CustomOperation("where",MaintainsVariableSpace=true,AllowIntoPattern=true)>]
member Where :
: source:QuerySource<'T,'Q> *
[<ProjectionParameter>] predicate:('T -> bool) -> QuerySource<'T,'Q>
The CustomOperation attribute defines the name of the operation. The (quite important) parameter MaintainsVariableSpace allows you to say that the operation returns the same type of values as it takes as the input. In that case, the variables defined earlier are still available after the operation. For example:
query { for p in db.Products do
let name = p.ProductName
where (p.UnitPrice.Value > 100.0M)
select name }
Here, the variables p and name are still accessible after where because where only filters the input, but it does not transform the values in the list.
Finally, the ProjectionParameter allows you to say that p.UnitValue > 100.0M should actually be turned into a function that takes the context (available variables) and evaluates this expression. If you do not specify this attribute, then the operation just gets the value of the argument as in:
query { for p in .. do
take 10 }
Here, the argument 10 is just a simple expression that cannot use values in p.
Pretty cool feature for the language. Just implemented the reverse to query QuerySource.
Simple example, but just a demonstration.
module QueryExtensions
type ExtendedQueryBuilder() =
inherit Linq.QueryBuilder()
/// Defines an operation 'reverse' that reverses the sequence
[<CustomOperation("reverse", MaintainsVariableSpace = true)>]
member __.Reverse (source : Linq.QuerySource<'T,System.Collections.IEnumerable>) =
let reversed = source.Source |> List.ofSeq |> List.rev
new Linq.QuerySource<'T,System.Collections.IEnumerable>(reversed)
let query = ExtendedQueryBuilder()
And now it being used.
let a = [1 .. 100]
let specialReverse =
query {
for i in a do
select i
reverse
}

How to declare an immutable graph with circular references?

I want to declare a graph of all states where the edges represent contiguous states. I think what I am trying to do might be called "tying the knot" (not sure about that though). It's not working like I expected, and I have a couple of questions.
First, I want a State type that has a string name and a list of contiguous states. But this declaration gives compiler error "...immediate cyclic reference...":
type State = string * (State list)
This way works:
type State(name:string, contigs: (State list)) =
let name = name
let contigs = contigs
But it's really not a requirement to name the members. A tuple is fine. How can I make that terse syntax work?
Second, the following code attempts to declare what should be three graphs of contiguous states (HI and AK are graphs consisting of a single node, all the remaining states constitute the last graph), followed by a list of all nodes. (For brevity I've only actually declared a handful of states here):
let rec hi = State("hi", [])
and mo = State("mo", [il ia])
and il = State("il", [mo])
and ia = State("ia", [mo])
and states = [hi,mo,il,ia]
This gives a variety of errors though including "mo will eventually be evaluated as part of it's own definition" and "expression was expected to have type 'a->'b but here has type State". I thought the 'rec' and 'and' keywords would allow this to work. Can I define this self referencing graph? If so, how?
The problem is your data structure and using invalid list element delimiters (should be semicolon). This works: (see edit)
type State =
| State of string * State list
let rec hi = State("hi", [])
and mo = State("mo", [il; ia])
and il = State("il", [mo])
and ia = State("ia", [mo])
let states = [hi; mo; il; ia]
Recursive references will be materialized as thunks (lazy). So you could, with a bit more typing do the same thing yourself with mutable lazys--just FYI--what you have is idiomatic.
EDIT
Intellisense didn't have a problem with it, but the compiler says
Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
You can fix this by using seq instead of list.
type State =
| State of string * State seq
let rec hi = State("hi", [])
and mo = State("mo", seq { yield il; yield ia })
and il = State("il", seq { yield mo })
and ia = State("ia", seq { yield mo })
let states = [hi; mo; il; ia]
Although what Daniel says is correct I would contest the assertion that it is "idiomatic" because that does not produce a very useful data structure for representing graphs in the general case. Specifically, it only permits the addition of new vertices and edges from them but not adding or removing edges between existing vertices. In particular, this basically means your graph must be statically defined as a constant in your source code so you cannot load such a graph from disk easily.
The idiomatic purely functional representation of a graph is to replace dereferences with dictionary lookups. For example, represent the graph as a Map from vertices to Sets of vertices to which there are edges:
> let g =
Map["hi", set[]; "mo", set["il"; "ia"]; "il", set["mo"]; "ia", set["mo"]];;
val g : Map<string,Set<string>> =
map
[("hi", set []); ("ia", set ["mo"]); ("il", set ["mo"]);
("mo", set ["ia"; "il"])]
For example, you can lookup the vertices directly reachable via edges from mo like this:
> g.["mo"];;
val it : Set<string> = set ["ia"; "il"]
This is easier to debug than the mutable representation but it has significant disadvantages:
Lookup in a purely functional dictionary like Map is at least 200× slower than dereferencing a pointer for traversing graphs (according to a quick test here).
The garbage collector no longer reclaims unreachable subgraphs for you. The imperative solution is to use a weak dictionary but there are no known purely functional weak dictionaries.
So this is only feasible if performance and leaks will not be a problem. This is most commonly the case when your graphs are small or static.

Is there a difference between foreach and map?

Ok this is more of a computer science question, than a question based on a particular language, but is there a difference between a map operation and a foreach operation? Or are they simply different names for the same thing?
Different.
foreach iterates over a list and performs some operation with side effects to each list member (such as saving each one to the database for example)
map iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members (such as converting a list of strings to uppercase)
The important difference between them is that map accumulates all of the results into a collection, whereas foreach returns nothing. map is usually used when you want to transform a collection of elements with a function, whereas foreach simply executes an action for each element.
In short, foreach is for applying an operation on each element of a collection of elements, whereas map is for transforming one collection into another.
There are two significant differences between foreach and map.
foreach has no conceptual restrictions on the operation it applies, other than perhaps accept an element as argument. That is, the operation may do nothing, may have a side-effect, may return a value or may not return a value. All foreach cares about is to iterate over a collection of elements, and apply the operation on each element.
map, on the other hand, does have a restriction on the operation: it expects the operation to return an element, and probably also accept an element as argument. The map operation iterates over a collection of elements, applying the operation on each element, and finally storing the result of each invocation of the operation into another collection. In other words, the map transforms one collection into another.
foreach works with a single collection of elements. This is the input collection.
map works with two collections of elements: the input collection and the output collection.
It is not a mistake to relate the two algorithms: in fact, you may view the two hierarchically, where map is a specialization of foreach. That is, you could use foreach and have the operation transform its argument and insert it into another collection. So, the foreach algorithm is an abstraction, a generalization, of the map algorithm. In fact, because foreach has no restriction on its operation we can safely say that foreach is the simplest looping mechanism out there, and it can do anything a loop can do. map, as well as other more specialized algorithms, is there for expressiveness: if you wish to map (or transform) one collection into another, your intention is clearer if you use map than if you use foreach.
We can extend this discussion further, and consider the copy algorithm: a loop which clones a collection. This algorithm too is a specialization of the foreach algorithm. You could define an operation that, given an element, will insert that same element into another collection. If you use foreach with that operation you in effect performed the copy algorithm, albeit with reduced clarity, expressiveness or explicitness. Let's take it even further: We can say that map is a specialization of copy, itself a specialization of foreach. map may change any of the elements it iterates over. If map doesn't change any of the elements then it merely copied the elements, and using copy would express the intent more clearly.
The foreach algorithm itself may or may not have a return value, depending on the language. In C++, for example, foreach returns the operation it originally received. The idea is that the operation might have a state, and you may want that operation back to inspect how it evolved over the elements. map, too, may or may not return a value. In C++ transform (the equivalent for map here) happens to return an iterator to the end of the output container (collection). In Ruby, the return value of map is the output sequence (collection). So, the return value of the algorithms is really an implementation detail; their effect may or may not be what they return.
Array.protototype.map method & Array.protototype.forEach are both quite similar.
Run the following code: http://labs.codecademy.com/bw1/6#:workspace
var arr = [1, 2, 3, 4, 5];
arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
console.log();
arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
They give the exact ditto result.
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
But the twist comes when you run the following code:-
Here I've simply assigned the result of the return value from the map and forEach methods.
var arr = [1, 2, 3, 4, 5];
var ar1 = arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar1);
console.log();
var ar2 = arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar2);
console.log();
Now the result is something tricky!
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
[ 1, 2, 3, 4, 5 ]
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
undefined
Conclusion
Array.prototype.map returns an array but Array.prototype.forEach doesn't. So you can manipulate the returned array inside the callback function passed to the map method and then return it.
Array.prototype.forEach only walks through the given array so you can do your stuff while walking the array.
the most 'visible' difference is that map accumulates the result in a new collection, while foreach is done only for the execution itself.
but there are a couple of extra assumptions: since the 'purpose' of map is the new list of values, it doesn't really matters the order of execution. in fact, some execution environments generate parallel code, or even introduce some memoizing to avoid calling for repeated values, or lazyness, to avoid calling some at all.
foreach, on the other hand, is called specifically for the side effects; therefore the order is important, and usually can't be parallelised.
Short answer: map and forEach are different. Also, informally speaking, map is a strict superset of forEach.
Long answer: First, let's come up with one line descriptions of forEach and map:
forEach iterates over all elements, calling the supplied function on each.
map iterates over all elements, calling the supplied function on each, and produces a transformed array by remembering the result of each function call.
In many languages, forEach is often called just each. The following discussion uses JavaScript only for reference. It could really be any other language.
Now, let's use each of these functions.
Using forEach:
Task 1: Write a function printSquares, which accepts an array of numbers arr, and prints the square of each element in it.
Solution 1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
Using map:
Task 2: Write a function selfDot, which accepts an array of numbers arr, and returns an array wherein each element is the square of the corresponding element in arr.
Aside: Here, in slang terms, we are trying to square the input array. Formally put, we are trying to compute it's dot product with itself.
Solution 2:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
How is map a superset of forEach?
You can use map to solve both tasks, Task 1 and Task 2. However, you cannot use forEach to solve the Task 2.
In Solution 1, if you simply replace forEach by map, the solution will still be valid. In Solution 2 however, replacing map by forEach will break your previously working solution.
Implementing forEach in terms of map:
Another way of realizing map's superiority is to implement forEach in terms of map. As we are good programmers, we'll won't indulge in namespace pollution. We'll call our forEach, just each.
Array.prototype.each = function (func) {
this.map(func);
};
Now, if you don't like the prototype nonsense, here you go:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
So, umm.. Why's does forEach even exist?
The answer is efficiency. If you are not interested in transforming an array into another array, why should you compute the transformed array? Only to dump it? Of course not! If you don't want a transformation, you shouldn't do a transformation.
So while map can be used to solve Task 1, it probably shouldn't. For each is the right candidate for that.
Original answer:
While I largely agree with #madlep 's answer, I'd like to point out that map() is a strict super-set of forEach().
Yes, map() is usually used to create a new array. However, it may also be used to change the current array.
Here's an example:
var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16]
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]
In the above example, a was conveniently set such that a[i] === i for i < a.length. Even so, it demonstrates the power of map().
Here's the official description of map(). Note that map() may even change the array on which it is called! Hail map().
Hope this helped.
Edited 10-Nov-2015: Added elaboration.
Here is an example in Scala using lists: map returns list, foreach returns nothing.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
So map returns the list resulting from applying the function f to each list element:
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)
Foreach just applies f to each element:
scala> var sum = 0
sum: Int = 0
scala> list foreach (sum += _)
scala> sum
res2: Int = 6 // res1 is empty
If you're talking about Javascript in particular, the difference is that map is a loop function while forEach is an iterator.
Use map when you want to apply an operation to each member of the list and get the results back as a new list, without affecting the original list.
Use forEach when you want to do something on the basis of each element of the list. You might be adding things to the page, for example. Essentially, it's great for when you want "side effects".
Other differences: forEach returns nothing (since it is really a control flow function), and the passed-in function gets references to the index and the whole list, whereas map returns the new list and only passes in the current element.
ForEach tries to apply a function such as writing to db etc on each element of the RDD without returning anything back.
But the map() applies some function over the elements of rdd and returns the rdd. So when you run the below method it won't fail at line3 but while collecting the rdd after applying foreach it will fail and throw an error which says
File "<stdin>", line 5, in <module>
AttributeError: 'NoneType' object has no attribute 'collect'
nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())

Resources