Neo4j / Cypher: Is CREATE UNIQUE deprecated? - neo4j

When I write a simple Cypher query like this:
MATCH (r:Person {name:'Jon'})
MATCH (s:Person {name:'Ana'})
CREATE UNIQUE (r)-[:FRIEND_OF]->(s)
I'm receiving an alert messsage in the Neo4j browser. The alert message says:
The RULE planner is not available in the current CYPHER version, the
query has been run by an older CYPHER version. CREATE UNIQUE is
unsupported for current CYPHER version, the query has been execute by
an older CYPHER version
Here a print screen of the alert message:
I searched by this message in the Neo4j Github and did not find anything. Also the docs has no mention to any depreciation.
My question is: Is CREATE UNIQUE deprecated? Why?
I'm using Neo4j 3.2.1.
Thanks.
PS: I know my query can be refactoring. It is only an example. Also all refactoring made in the query using CREATE UNINQUE show the same alert message in the Neo4j browser.

CREATE UNIQUE is set to be completely replaced by MERGE. So your syntax would be :
MATCH (r:Person {name:'Jon'})
MATCH (s:Person {name:'Ana'})
MERGE (r)-[:FRIEND_OF]->(s)
Regards,
Tom

Try this
MATCH (lft:Person {name:'Jon'}),(rgt)
WHERE rgt.name IN ['Ana']
CREATE UNIQUE (lft)-[r:KNOWS]->(rgt)
RETURN r
note that you can search for multiple names too like this
MATCH (lft:Person {name:'Jon'}),(rgt)
WHERE rgt.name IN ['Ana','Maria']
CREATE UNIQUE (lft)-[r:KNOWS]->(rgt)
RETURN r

Related

Not able to create a node with special characters "-" in neo4j

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/

How to force Neo4j to use 2 indexes?

I mean, if I have two indexes:
CREATE INDEX ON :labelA(idA)
CREATE INDEX ON :labelB(idB)
And I do the following query:
MATCH (n:labelA {idA: valA})
MATCH (n:labelB {idB: valB})
CREATE (n)-[:Rel]->(B)
Does neo4j just use one of the indexes? If does, How do I force neo4j to use the 2 indexes?.
Thanks in advance.
Currently Neo will only use a maximum of one index to determine where to start walking the graph as part of query resolution. This is likely to change in the future. You can give Neo hints on which of the 2 or more indexes to use via USE INDEX but you can't get it to use more than one at this point.
You could check if indexes are being used to find the nodes by prepending your query with PROFILE.
You could throw the query optimizer a hint something like this...
MATCH (a:labelA {idA: valA}), (b:labelB {idB: valB})
USING INDEX a:LabelA(idA)
USING INDEX b:LabelB(idB)
CREATE (a)-[:Rel]->(b)

Neo4j filtering Cypher query on relationships

I am trying to retrieve the paths from Airport(A1) to Airport(A3) based on their relationships, when the arrival-time is less than departure-time.
here is my console link http://console.neo4j.org/r/7cw8h0
You had it almost right (you also misspelt your property value for Airport A1)
MATCH path =((A1:AIRPORT)-[Connections:Connect*]->(A3:AIRPORT))
WHERE A1.name='Airport A1' AND A3.name='Airport A3'
AND ALL (i IN Range(0, length(Connections)-2)
WHERE ((Connections[i]).arrvTime <(Connections[i+1]).dptrTime))
RETURN extract(Connect IN Connections | Connect.flightcode)
Your console was also not shared correctly, here is a correct version:
http://console.neo4j.org/r/jfxnsj
This might also be interesting for you:
http://maxdemarzi.com/?s=flights
http://gist.neo4j.org/?6619085

Parse a big file and populate a Neo4j database

I am working on a Ruby on Rails project that will read and parse somewhat big text file (around 100k lines) and build Neo4j nodes (I am using Neography) with that data.
This is the Neo4j related fraction of the code I wrote:
d= Neography::Rest.new.execute_query("MATCH (n:`Label`) WHERE (n.`name`='#{id}') RETURN n")
d= Neography::Node.load(d, #neo)
p= Neography::Rest.new.create_node("name" => "#{id}")
Neography::Rest.new.add_label(p, "LabelSample")
d=Neography::Rest.new.get_node(d)
Neography::Rest.new.create_relationship("belongs_to", p, d)
so, what I want to do is: a search in the already populated db for the node with the same "name" field as the parsed data, create a new node for this data and finally create a relationship between the two of them.
Obiously this code simply takes way too much time to be executed.
So I tried with Neography's batch, but I ran into some issues.
p = Neography::Rest.new.batch [:create_node, {"name" => "#{id}"}]
gave me a "undefined method `split' for nil:NilClass" in
id["self"].split('/').last
d=Neography::Rest.new.batch [:get_node, d]
gives me a Neography::UnknownBatchOptionException for get_node
I am not even sure this will save me enough time either.
I also tried different ways to do this, using Batch Import for example, but I couldn't find a way to get the already created node I need from the db.
As you can see I'm kinda new to this so any help will be appreciated.
Thanks in advance.
You might be able to do this with pure cypher (or neography generated cypher). Something like this perhaps:
MATCH (n:Label) WHERE n.name={id}
WITH n
CREATE (p:LabelSample {name: n.name})-[:belongs_to]->n
Not that I'm using CREATE, but if you don't want to create duplicate LabelSample nodes you could do:
MATCH (n:Label) WHERE n.name={id}
WITH n
MERGE (p:LabelSample {name: n.name})
CREATE p-[:belongs_to]->n
Note that I'm using params, which are generally recommended for performance (though this is just one query, so it's not as big of a deal)

How to use START with Cypher / Neo4j 2.0

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.

Resources