23. How does Neo4j use indexes?
Indexes are only used to find the starting point
for queries.
Use index scans to look up
rows in tables and join them
with rows from other tables
Use indexes to find the starting
points for a query.
Relational
Graph
24. Create Index / Constraint
CREATE INDEX ON :Business(name);
CREATE CONSTRAINT ON (u:User) ASSERT u.user_id IS UNIQUE;
CREATE CONSTRAINT ON (b:Business) ASSERT b.business_id IS UNIQUE;
CREATE CONSTRAINT ON (c:Category) ASSERT c.name IS UNIQUE;
CREATE CONSTRAINT ON (b:Review) ASSERT b.review_id IS UNIQUE;
hEp://neo4j.com/docs/developer-manual/current/cypher/schema/constraints/
Constraint + index
Index
26. PERIODIC COMMIT
USING PERIODIC COMMIT 2000
LOAD CSV WITH HEADERS FROM “file:///review.csv" AS row
MATCH (u:User {user_id: row.user_id})
MATCH (b:Business {business_id: row.business_id})
MATCH (r:Review {review_id: row.review_id})
MERGE (u)-[:WROTE]->(r)
MERGE (r)-[:REVIEW_OF]->(b)
hEps://neo4j.com/docs/developer-manual/current/cypher/clauses/using-periodic-commit/
27. Naive Import
LOAD CSV WITH HEADERS FROM "file:///reviews.csv" AS row
MERGE (b:Business {business_id: row.business_id})
MERGE (u:User {user_id: row.user_id})
MERGE (r:Review {review_id: row.review_id})
ON CREATE SET r.stars = toInteger(row.stars),
r.text = row.text
MERGE (r)-[:REVIEW_OF]->(b)
MERGE (u)-[rr:WROTE]-(r)
ON CREATE SET rr.date = row.date
28. Break Up MERGEs
LOAD CSV WITH HEADERS FROM “file:///business.csv" AS row
MERGE (b:Business {business_id: row.business_id})
ON CREATE SET b.name = row.name …
LOAD CSV WITH HEADERS FROM “file:///user.csv” AS row
MERGE (b:User {user_id: row.user_id})
ON CREATE SET b.name = row.name …
LOAD CSV WITH HEADERS FROM “file:///review.csv" AS row
MATCH (u:User {user_id: row.user_id})
MATCH (b:Business {business_id: row.business_id})
MATCH (r:Review {review_id: row.review_id})
MERGE (u)-[:WROTE]->(r)
MERGE (r)-[:REVIEW_OF]->(b)
LOAD CSV WITH HEADERS FROM “file:///review.csv” AS row
MERGE (r:Review {review_id: row.review_id})
ON CREATE SET r.stars = row.stars …
29. cypher-shell
hEps://neo4j.com/docs/operaMons-manual/current/tools/cypher-shell/
cat simple_load_csv.cypher | …/bin/cypher-shell …
Replaces `neo4j-shell` in Neo4j 3.x+
Run multi-line Cypher scripts
--format=verbose (to get the same output as in 'neo4j-shell')
• Every cypher statement must be ended with a ';'
• It is possible to start, commit and rollback a transacMon
On Windows:
powershell
PS>type simple_load_csv.cypher | …bincypher-shell.bat …
36. apoc.load.jdbc
// Table check
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=yelp"
as url
call apoc.load.jdbc(url,"select * from user limit 10") yield row
return row
• No need for export to csv!
• Much more type save, no escaping of 'csv' breaking characters anymore.
• Just replace the LOAD CSV line with CALL apoc.load.jdbc(...) yield row
37. apoc.load.jdbc
// Import user table #user: 1183362
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=
as url
call apoc.load.jdbc(url,"select name, id as user_id
, review_count, average_stars, fans from user") yield row
MERGE (u:User {user_id: row.user_id})
SET u.name = row.name,
u.review_count = row.review_count,
u.average_stars = row.average_stars,
u.fans = row.fans
Can be placed in conf file!
38. apoc.load.jdbc
// Import friend table #friend: 39846890
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=
as url
call apoc.load.jdbc(url,"select friend_id, user_id from friend") y
MERGE (u:User {user_id: row.user_id} )
MERGE (f:User {user_id: row.friend_id} )
MERGE (u)-[:FRIENDS]->(f)
39. // Import business table #business: 156639
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=yelp"
as url
call apoc.load.jdbc(url,"select city, name, id as business_id
, stars, latitude, longitude, postal_code, address
, state, review_count, neighborhood from business") yield row
MERGE (b:Business {business_id: row.business_id})
SET b.address = row.address,
b.lat = row.latitude,
b.lon = row.longitude,
b.name = row.name,
b.city = row.city,
b.postal_code = row.postal_code,
b.state = row.state,
b.review_count = row.review_count,
b.stars = row.stars,
b.neighborhood = row.neighborhood
40. // Import (business) category #category: 590290
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=yelp"
as url
call apoc.load.jdbc(url,"select business_id, category from category") yield row
MATCH (b:Business {business_id: row.business_id})
MERGE (c:Category { name : row.category })
MERGE (b)-[:IN_CATEGORY]->(c)
41. // Import review table #review: 4736897
with "jdbc:mysql://192.168.56.102:3306/yelp_db?user=yelp&password=yelp"
as url
call apoc.load.jdbc(url,"select id as review_id, user_id
, business_id, text, stars, useful from review ") yield row
MERGE (b:Business {business_id: row.business_id})
MERGE (u:User {user_id: row.user_id})
MERGE (r:Review {review_id: row.review_id})
ON CREATE SET r.text = row.text,
r.date = row.date,
r.stars = row.stars,
r.useful = row.useful
MERGE (u)-[:WROTE]->(r)
MERGE (r)-[:REVIEWS]->(b)
46. neo4j-import file format
:ID(User) :LABEL name
123 User Will
124 User Bob
125 User Heather
126 User Erika
:ID(Review) :LABEL stars:int
127 Review 3
128 Review 2
129 Review 5
130 Review 1
:START_ID(User) :END_ID(Review) :TYPE
123 127 WROTE
124 128 WROTE
125 129 WROTE
126 130 WROTE
RelaMonships
Nodes