I tried to merge a node with apoc.merge.node but my ident property keys have a special char(:) and get double escaped. Did i miss something or does a workaround exist?
If i replace the ":" with "_" everything works as expected.
Neo4j 4.2.1 community and APOC 4.2.0
CALL apoc.merge.node(["test"], apoc.map.fromPairs([["i:d","123"]])) YIELD node return node
Error
Failed to invoke procedure `apoc.merge.node`: Caused by: org.neo4j.exceptions.SyntaxException: Invalid input 'i': expected "}" (line 1, column 17 (offset: 16))
"MERGE (n:test{``i:d``:$identProps.``i:d``}) ON CREATE SET n += $onCreateProps ON MATCH SET n += $onMatchProps RETURN n"
EDIT
It seems there is a bug in APOC which causes the identifier to be encoded twice.
First with Util::quote https://github.com/neo4j-contrib/neo4j-apoc-procedures/blob/4.1/core/src/main/java/apoc/util/Util.java#L674
And then in the merge procedure https://github.com/neo4j-contrib/neo4j-apoc-procedures/blob/4.1/core/src/main/java/apoc/merge/Merge.java#L85
I've filed an issue: https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1783
In Neo4j, you can use backticks ` around a key that contain special characters :
CALL apoc.merge.node(["test"], apoc.map.fromPairs([["`i:d`","123"]]))
YIELD node
return node
Same is true everywhere in the Cypher syntax, escaping a label with a whitespace for eg :
MERGE (n:`Land Vehicle` {id: "land-rover-1"})
Related
When defining a syntax, it is possible to match 1 or more times (+) or 0 or more times (*) similarly to how it is done in regex. However, I have not found in the rascal documentation if it is possible to also match a Symbol a specific amount of times. In regex (and Rascal patterns) this is done with an integer between two curly brackets but this doesn't seem to work for syntax definition. Ideally, I'd want something like:
lexical Line = [0-9.]+;
syntax Sym = sym: {Line Newline}{5};
Which would only try to match the first 5 lines of the text below:
..0..
11.11
44.44
1.11.1
33333
55555
No this meta syntax does not exist in Rascal. We did not add it.
You could write an over-estimation like this and have a post-parse filter reject more than 5 items:
syntax Sym = fiveLines: (Line NewLine)+ lines
visit (myParseTree) {
case (Sym) `<(Line NewLine)+ lines>` :
throw ParseError(x.src) when length(lines) != 5;
}
Or unfold the loop like so:
syntax Sym
= Line NewLine
Line NewLine
Line NewLine
Line NewLine
Line NewLine
;
Repetition with an integer parameter sounds like a good feature request for us the consider, if you need it badly. We only have to consider what it means for Rascal's type-system; for the parser generator its a simple rule to add.
I have some syntax in project C# that using DB neo4j. In this WithParam, I can not understand about its syntax
var data = WebApiConfig.GraphClient.Cypher
.Match("(m:Movie)")
.Where("m.title =~ {title}")
.WithParam("title", "(?i).*" + q + ".*")
.Return<Movie>("m")
.Results.ToList();
You should review the Cypher parameters documentation. Parameters passed with a query are referenceable by a special syntax (the "title" parameter was passed as a parameter, so you would use $title to use it in the query, or {title} if using the older parameter syntax).
As for the value of the parameter itself, "title" is a regex string. (?i) means it's case insensitive, .* means match 0 or more characters, then the q variable from your code is appended in, followed by another .* for matching any additional characters. The place of usage of the parameter uses the regex comparison operator =~ which interprets the regex string correctly.
This is a case-insensitive comparison, looking for any :Movie nodes with a title property that contains whatever the q string is, regardless of case.
This Cypher statement causes a syntax error:
CREATE (mediawiki-1.27:Schema { key: mediawiki-1.27, name:mediawiki-1.27})
The error seems to be caused by the - character in the node label:
Invalid input '1': expected whitespace, [ or '-' (line 1, column 19 (offset: 18))
"CREATE (mediawiki-1.27:Schema { key: mediawiki-1.27, name:mediawiki-1.27})"
Dashes and dots are not allowed in variable names. You can surround the variable name with backticks to escape it.
Also I'm guessing your key and name values are strings, in which case make sure to surround them with quotes:
CREATE (`mediawiki-1.27`:Schema { key:'mediawiki-1.27', name:'mediawiki-1.27'})
MATCH (p:Product {id:'19134046594'})-[r]-> (o:Attributes {4g:'network'}) return o
I received this exception:
Exception in thread "main" java.lang.RuntimeException: org.neo4j.driver.v1.exceptions.ClientException: Invalid input ':': expected an identifier character, whitespace or '}' (line 1, column 66 (offset: 65))
It's complaining about '4g'. Is '4g' an invalid property key identifier in neo4j? How to work around the issue?
You can use the backtick (`) character to quote property names that start with an otherwise illegal character.
For example, this would work:
CREATE (o:Attributes {`4g`: 'network'})
RETURN o;
And this also works:
MATCH (o:Attributes) WHERE o.`4g` = 'network'
RETURN o;
According to the naming rules section of the documentation, names you use (which does include property keys):
Must begin with an alphabetic letter.
and
Can contain numbers, but not as the first character.
You can however start it off with an underscore, so _4g:'network' would work.
I'm guessing this is just for example purposes, but it does seem to me that it would be better the other way around: network:'4g'.
VB.NET program that loads a few thousand nodes and set up relationships between them. I'm using the Neo4J C# Client (version 1.1.0.8)
One of the commands is
TheConnection.GraphClient.Cypher.Match(
"(user1:StartingPoint)",
"(user2:Committee)"
).Where(
Function(user1 As StartingPoint)
user1.Id = KnowsID
).AndWhere(
Function(user2 As Committee)
user2.Id = KnownID
).Create(
"user1-[r: Knows ]->user2"
).ExecuteWithoutResults()
For various business logic reasons I want to match the nodes by FECIDNumber (it's actually a string, in example 'C00530767') instead of ID. So I changed
KnownID from Long to String
user2.Id = KnownID
This gives me following query
TheConnection.GraphClient.Cypher.Match(
"(user1:StartingPoint)",
"(user2:Committee)"
).Where(
Function(user1 As StartingPoint)
user1.Id = KnowsID
).AndWhere(
Function(user2 As Committee) user2.FECIDNumber = KnownID
).Create(
"user1-[r: Knows ]->user2"
).ExecuteWithoutResults()
When executed it throws
{"SyntaxException: Invalid input '{':expected an identifier character, whitespace, '?', '!', '.', node labels, '[', ""=~"", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', ""<>"", ""!="", '<', '>', ""<="", "">="", AND, XOR, OR or ')' (line 3, column 23 (offset: 95))" & vbLf & """AND (user2.FECIDNumber{p1}{p2} = {p3})" & vbCr & """" & vbLf & " ^"}
When I go into the Neo4J Browser and run
MATCH (user:Committee) WHERE user.FECIDNumber = "C00530766" RETURN user
it returns the node as expected.
I think the important part of the error seems to be
(line 3, column 23 (offset: 95))
" & vbLf & """AND (user2.FECIDNumber{p1}{p2} = {p3})" & vbCr & """" & vbLf & "
It looks like the Neo4J C# Client is tossing in a second parameter {p2}, but that's just a guess.
Any suggestions?
Edit 1
(I didn't know I could even pull the raw query text)
It's returning
MATCH (user1:StartingPoint), (user2:Committee)
WHERE (user1.Id = 1)
AND (user2.FECIDNumber"C00530766"false = 0)
CREATE user1-[r: Knows ]->user2
Clearly the problem is that
user2.FECIDNumber = KnownID).Create("user1-[r: Knows ]->user2")
is somehow generating
user2.FECIDNumber"C00530766"false = 0
Ideas? Is there a different syntax I should be using? Do I need to convert FECIDNumber to a different type?
Edit 2
The same code now generates
MATCH (user1:StartingPoint), (user2:Committee)
WHERE (user1.Id = 1)
AND (user2.FECIDNumber = "C00530766")
CREATE user1-[r: Knows ]->user2
And it creates the relationship as expected.
Winner.....
I have published a version (1.1.0.26) which should resolve this for you, it'll take a few mins for Nuget to index it, so give it 1/2 an hour or so from when this is posted...
Let me know!