Creating a co-authorship graph - neo4j

I am analysing an author dataset and I wish I could create a co-authorship graph from this dataset. A author graph was created using CYPHER, just this way:
CREATE (N0{data:"2007-12-18", title:"ABC"}),
(N2 {data:"2007-10-20",title:"BBB"}),
(N3 {data:"2007-08-02",title:"CCC"}),
(N4 {name:"xxx"}),
(N5 {name:"yyy"}),
(N6 {name:"zzz"}),
N4-[R0:autor_de]->N0,
N5-[R1:autor_de]->N0,
N6-[R2:autor_de]->N2,
N5-[R3:autor_de]->N3;
I can't figure out how to create a new graph so that authors were linked by a new relationship such as "are_coauthors". Sorry if this is a very simple question, I know that this can solved using Java and (maybe) py2neo, but does someone has any hint?

In cypher you can do something like (assuming an autoindex on title):
start title=node:node_auto_index("title:*")
match a-[:autor_de]->title<-[:autor_de]-b
create unique a-[:coautores]-b
To create a link between coauthors.

Related

how to create multiple relationships in a single cypher statement

I must create a set of relationships, all having the same source and type, like in the following sample:
create (_1)-[:`typ`]->(:`x` {`name`:"Mark"})
create (_1)-[:`typ`]->(:`y` {`name`:"Jane"})
create (_1)-[:`typ`]->(:`z` {`name`:"John"})
...
I'd like to have a shorten way to write those statements, like following attempt?
create (_1)-[:`typ`]->[(:`x` {`name`:"Mark"}),
(:`y` {`name`:"Jane"}),
(:`z` {`name`:"John"})]
Any idea?
Thank you in advance.
Paolo
You could do it in a performant and easy way by this pattern:
{batch: [
{from:"alice#example.com",to:"bob#example.com",properties:{since:2012}},
{from:"alice#example.com",to:"charlie#example.com",properties:{since:2016}}]}
UNWIND {batch} as row
MATCH (from:Label {row.from})
MATCH (to:Label {row.to})
CREATE/MERGE (from)-[rel:KNOWS]->(to)
(ON CREATE) SET rel += row.properties
Taken with thanks from 5 Tips & Tricks for Fast Batched Updates of Graph Structures with Neo4j and Cypher by #MichaelHunger.

Neo4j / Cypher: Is CREATE UNIQUE deprecated?

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

How to create a relation between two node having same node name in neo4j

I want to create a friends relation between abcd node and vbnm node having same node-name - Student
neo4j graph database visualization
I execute the following query, It doesn't show me any error but this query doesn't create any relation
match(Student:Stu),(Student:Stu)where Student.name="abcd" AND Student.name="vbnm" create(Student)-[fr:friends]->(Student)
You need use different variable name:
match(Student1:Stu),(Student2:Stu)
where Student1.name="abcd" AND
Student2.name="vbnm"
create(Student1)-[fr:friends]->(Student2)
I think you are confused by the syntax a little bit. Let me give you an example of a MATCH query syntax.
MATCH (variable1:Label),(variable2:Label) where variable1.foo = variable2.foo
You mixed label and variable in your query and each entity should have its own variable (variable1 and variable2) so you can interact with them.
So in your case the optimal query looks something like:
MATCH (s1:Student),(s2:Student ) where s1.name="abcd" AND s2.name="vbnm"
CREATE (s1)-[:friends]->(s2)
Note that you do not need to assign a variable to [:friends] relationship as you do not interact with it later in the same query.

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)

Neo4J - Simple "follower" graph

I'm attempting to create a simple Twitter-esque "follower / friend" graph using Neo4J and Python. The graph would look something like
user_1 FOLLOWS user_2
user_1 FOLLOWS user_3
user_2 FOLLOWS user_1
After a day of reading I thought it best to dive straight in using the REST interface and, since I'm using Python, py2neo. Here is my code:
from py2neo import neo4j
def main():
g = neo4j.GraphDatabaseService()
# Create an index for our user nodes
index = g.get_or_create_index(neo4j.Node, "user")
# Create a single node, User 1
node = index.get_or_create("user", "User_1", {"id": "User_1"})
# Populate the graph with some more users just for testing
nodes = []
for user in ["User_2", "User_3", "User_4", "User_5"]:
nodes.append( index.get_or_create("user", user, {"id":user}) )
# Create a relationship between User_1 and User_2
g.get_or_create_relationships( (node, "FOLLOWS", nodes[0]) )
if __name__ == '__main__':
main()
As you can see, I'm using get_or_create_relationships to prevent duplicate relationships and when adding thousands of nodes I'm assuming this is going to incur some kind of overhead.
Using straight up "node.create_relationship_to(nodes[0], "FOLLOWERS")" seems to create duplicate relationships each time the script is run which for a graph db newbie confuses me slightly since the relationship is exactly the same.
The likelihood of creating duplicate relationships is very low but in the event it were to happen, would this cause issues with graph traversal? Should I be indexing my FOLLOWS index with some kind of unique function?
I would use cypher CREATE UNIQUE to only create a FOLLOWs releationship if there is none existing, see http://docs.neo4j.org/chunked/milestone/query-create-unique.html
Would that work?

Resources