I am trying example provided in Graph Databases book (PDF page 51-52)with Neo4j 2.0.1 (latest). It appears that I cannot just copy paste the code sample from the book (I guess the syntax is no longer valid).
START bob=node:user(username='Bob'),
charlie=node:user(username='Charlie')
MATCH (bob)-[e:EMAILED]->(charlie)
RETURN e
Got #=> Index `user` does not exist.
So, I tried without 'user'
START bob=node(username='Bob'),
charlie=node(username='Charlie')
MATCH (bob)-[e:EMAILED]->(charlie)
RETURN e
Got #=> Invalid input 'u': expected whitespace, an unsigned integer, a parameter or '*'
Tried this but didn't work
START bob=node({username:'Bob'}),
(charlie=node({username:'Charlie'})
MATCH (bob)-[e:EMAILED]->(charlie)
RETURN e
Got #=> Invalid input ':': expected an identifier character, whitespace or '}'
I want to use START then MATCH to achieve this. Would appreciate little bit of direction to get started.
From version 2.0 syntax has changed.
http://docs.neo4j.org/chunked/stable/query-match.html
Your first query should look like this.
MATCH (bob {username:'Bob'})-[e:EMAILED]->(charlie {username:'Charlie'})
RETURN e
The query does not work out of the box because you'll need to create the user index first. This can't be done with Cypher though, see the documentation for more info. Your syntax is still valid, but Lucene indexes are considered legacy. Schema indexes replace them, but they are not fully mature yet (e.g. no wildcard searches, IN support, ...).
You'll want to use labels as well, in your case a User label. The query can be refactored to:
MATCH (b:User { username:'Bob' })-[e:EMAILED]->(c:User { username:'Charlie' })
RETURN e
For good performance, add a schema index on the username property as well:
CREATE INDEX ON :User(username)
Start is optional, as noted above. Given that it's listed under the "deprecated" section in the Cypher 2.0 refcard, I would try to avoid using it going forward just for safety purposes.
However, the refcard does state that you can prepend your Cypher query with "CYPHER 1.9" (without the quotes) in order to make explicit use of the older syntax.
Related
I am new to Neo4j and I have a relatively complex (but small) database which I have simplified to the following:
The first door has no key, all other doors have keys, the window doesn't require a key. The idea is that if a person has key:'A', I want to see all possible paths they could take.
Here is the code to generate the db
CREATE (r1:room {name:'room1'})-[:DOOR]->(r2:room {name:'room2'})-[:DOOR {key:'A'}]->(r3:room {name:'room3'})
CREATE (r2)-[:DOOR {key:'B'}]->(r4:room {name:'room4'})-[:DOOR {key:'A'}]->(r5:room {name:'room5'})
CREATE (r4)-[:DOOR {key:'C'}]->(r6:room {name:'room6'})
CREATE (r2)-[:WINDOW]->(r4)
Here is the query I have tried, expecting it to return everything except for room6, instead I have an error which means I really don't know how to construct the query.
with {key:'A'} as params
match (n:room {name:'room1'})-[r:DOOR*:WINDOW*]->(m)
where r.key=params.key or not exists(r.key)
return n,m
To be clear, I don't need my query debugged so much as help understanding how to write it correctly.
Thanks!
This should work for you:
WITH {key:'A'} AS params
MATCH p=(n:room {name:'room1'})-[:DOOR|WINDOW*]->(m)
WHERE ALL(r IN RELATIONSHIPS(p) WHERE NOT EXISTS(r.key) OR r.key=params.key)
RETURN n, m
With your sample data, the result is:
╒════════════════╤════════════════╕
│"n" │"m" │
╞════════════════╪════════════════╡
│{"name":"room1"}│{"name":"room2"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room3"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room4"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room5"}│
└────────────────┴────────────────┘
I am trying to create a node in neo4j(version 3.2.3). Below is the cypher query,
MERGE (`source-real-address`:SOURCE {Source:{`source-real-address`}})
I found in forums to create a node with special characters we should use
backticks `
in the query. But I couldn't able to create a node with backticks. No error were thrown in the logs.
Could you please help me to resolve this?
Please correct me if I am doing anything wrong in the cypher query. I am started
to understand neo4j cypher query language.
Note:- I am sending data to neo4j from graylog with the help of neo4j output plugin. I could able to create node without special character fields.
The syntax {Source:{`source-real-address`}}) means that you are trying to use a param named source-real-address as the value of the property Source. If this is your goal, you can set a param in the Neo4j Browser for test purposes with :params {"source-real-address":"Some value"}. If not, you can remove the extra { and } in the value and use "" instead of backticks, like this:
MERGE (source-real-address:SOURCE {Source:"source-real-address"})
Remeber that the value of a property should be Boolean, Integer, Float or String.
In Cypher backticks are used to create relationships, labels and variable names with special chars (not for property values).
Use the CREATE command to create Node with special characters
see this also: https://neo4j.com/docs/cypher-manual/current/syntax/naming/
We are using the new Cypher 3.1 head() function and are seeing some unusual (wrong?) behavior when it is used in a RETURN statement after an OPTIONAL MATCH command. It looks like values that the labels that don't match in the optional match negatively affect the data already collected from the head() perspective, while working as expected for the rest of the RETURN statement. Any ideas on what we're doing wrong or is this an unintended consequence in the Neo4j engine?
MATCH (productLine:ProductLine)-[:CHILD]->(product:Product)-[:CHILD]->(application:Application)-[:MATCHES]->(:Rule {name: 'Tier-0 Application'})
WITH productLine,
application
OPTIONAL MATCH (application)-[mr:MATCHES]->(:Rule {name: 'Multiple Regions'})
WITH application,
mr,
productLine
RETURN
productLine.name AS ProductLine,
head([(productLine)-[:PRODUCT_MANAGER]->(person:Person) | person.name]) AS ProductLineManager,
mr.numServers,
application.id AS AppId
Here's what we see:
ProductLine ProductLineManager mr.numServers AppId
PL1 null null IN000041
PL2 LAST,FIRST 6 AP010024
PL3 LAST,FIRST 6 AP107752
PL4 LAST,FIRST 11 AP106560
PL5 null null AP012190
Looks like this is a bug related to pattern comprehension, not the head() function, when there are rows generated by an an OPTIONAL MATCH.
I was able to reproduce the bug using the movies graph as a base.
I created a bug for this on the Neo4j issues tracker, complete with examples.
As a workaround, it looks like using DISTINCT on either the last WITH or on the RETURN may cause it to return expected results.
I'm new programming with Neo4j, so I don't know enough from it's cypher language yet to solve without help an annoying bug from legacy and undocumented code.
My main problem is that I can't guess the purpose of the following query... :s .
That's the problematic query:
START
n=node({self})
MATCH
n-[:RECOMMENDATION]->(m)
WHERE
m.concept_type='unifying_theme' AND
not( ()-[:REQUIRED]->m ) RETURN m
The query itself is written with only one line, I've formatted it to make more readable. The error message is the following (reformatted to be easier to read):
PatternException: Some identifiers are used as both relationships and nodes:
UNNAMED1 Query:
START n=node({self})
MATCH n-[:RECOMMENDATION]->(m)
WHERE m.concept_type='unifying_theme' AND not( ()-[:REQUIRED]->m )
RETURN m
Params: {'self': 423}
Trace:
org.neo4j.cypher.internal.pipes.matching.PatternGraph.validatePattern(PatternGraph.scala:98)
org.neo4j.cypher.internal.pipes.matching.PatternGraph.<init>(PatternGraph.scala:36)
org.neo4j.cypher.internal.executionplan.builders.PatternGraphBuilder$cla...
The query is embedded inside a NeoModel's python library "StructuredNode" instance. I guess the {self} refers to the node represented by the StructuredNode instance, and that the error if this query is related with the m variable...
I suppose maybe I should use more variable names to avoid conflicts, but I'm suspicious. I think there are more errors on this query because I've seen more ugly and buggy code of this disastrous programmer.
I don't know what was trying to do with the not( ()-[:REQUIRED]->m ) block, Is that a legal Cypher "subsentence" if m represents a node?
P.D.: I'm using Neo4j 1.9.7 .
Thank you in advance.
I'm begining with Neo4j/Cypher, I have some nodes containing a property which is an array of integers. I want to check if a given number is in a node's collection and if so, append this node to the results. My query looks like this:
MATCH (a) WHERE has(a.user_ids) and (13 IN a.user_ids) RETURN a
where 13 is the given user_id. It throws a syntax error:
Type mismatch: a already defined with conflicting type Node (expected Collection<Any>)
Any idea how can I accomplish that?
Thanks in advance.
You can try the predicate ANY, which returns true if any member of a collection matches some criterion.
MATCH (a) WHERE has(a.user_ids) and ANY(user_id IN a.user_ids WHERE user_id = 13)
It looks a bit backwards now that I'm looking at it, but it should work.
Edit:
It was bugging me why your query didn't work and why my answer seemed backwards and indirect so I did a simple test. Basically, your original query works if you put the property reference in parentheses:
MATCH (a)
WHERE has(a.user_ids) and (13 IN (a.user_ids))
RETURN a
That's easier to read so that's what I should have answered. But I still couldn't see why the parentheses where necessary here, when they are not in other cases. They were not necessary inside the ANY() above, and if you 'detach' the collection from the node
MATCH (a)
WITH a.user_ids as user_ids, a
WHERE 13 IN user_ids
RETURN a
there's no problem. For some reason Cypher needs to be told to evaluate a.user_ids before IN, or it ignores user_ids and tries to evaluate 13 IN a. IN is listed as an operator in the documentation, but in this regard it woks differently than other operators. For example
MATCH (a) RETURN 13 + a.user_ids
returns fine and
MATCH (a) RETURN 13 * a.user_ids
MATCH (a) RETURN 13 < a.user_ids
fails but because a.user_ids is a collection, not because a is a node. It's probably not very important, it's easy enough to use parentheses, but it would be interesting to learn why they are necessary.
I also compared my answer to your original query with added parentheses to see if there were any performance drawback to the more indirect way. Turns out the execution plan is almost identical, 13 IN (a.user_ids) is refactored to use ANY() like in my answer.
My answer:
Filter(pred="any(user_id in Product(a,user_ids(6),true) where user_id == Literal(13))", _rows=1, _db_hits=8)
AllNodes(identifier="a", _rows=8, _db_hits=8)
Your query + ():
Filter(pred="any(-_-INNER-_- in Product(n,user_ids(6),true) where Literal(13) == -_-INNER-_-)", _rows=1, _db_hits=8)
AllNodes(identifier="n", _rows=8, _db_hits=8)
Finally, in your case you probably don't have to check for existence of property with has(). Absent properties and null are handled differently in 2.0 and if the property doesn't exist 13 IN (a.user_ids) will evaluate to false, so usually there is no reason to test for property existence before property evaluation for fear of the query breaking. The place to use has() would be when property existence is relevant in itself, and that would probably be a different property than the one evaluated, i.e. WHERE has(a.someProperty) AND 13 IN (a.someOtherProperty).
Since there is no performance difference, the more readable query is better, and since you, as far as I can see, don't really need to test for property existence, I think your query should be
MATCH (a)
WHERE 13 IN (a.user_ids)
RETURN a