본문 바로가기

문돌이 존버/DB 및 SQL 스터디

Neo4j import csv & create node

반응형

csv 파일을 임포트해서 노드를 만드는 방법입니다. 

// Create orders
LOAD CSV WITH HEADERS FROM 'file:///orders.csv' AS row
MERGE (order: Order {orderID: row.OrderID})
ON CREATE SET order.shipName = row.ShipName;

아래는 노드에 인덱스 및 유니크 제약 조건을 두는 쿼리문입니다. 

CREATE INDEX product_id FOR (p:Product) ON (p.productID);
CREATE CONSTRAINT order_id ON (o:Order) ASSERT o.orderID IS UNIQUE;
:schema // 각 노드 정보 및 제약 조건 확인

이제 Order과 Product라는 노드가 생성되었다고 가정하고, 아래 두 노드 간 "CONTAINS'라는 관계를 생성해보겠습니다. 

// Create relationships between orders and products
LOAD CSV WITH HEADERS FROM 'file:///orders.csv' AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (product:Product {productID: row.ProductID})
MERGE (order)-[op:CONTAINS]->(product)
  ON CREATE SET op.unitPrice = toFloat(row.UnitPrice), op.quantity = toFloat(row.Quantity);
call db.schema.visualization()

아래는 제품 Chocolade를 산 고객의 회사명을 구해보는 쿼리문입니다. 

MATCH (:Product {productName:"Chocolade"})
<-[:CONTAINS]-(:Order)<-[:PURCHASED]-(c:Customer)
RETURN c.companyName as Company;

위 쿼리문을 실행하려면 Customer라는 노드도 필요한데요. 그대로 따라해보실 분은 아래 쿼리를 먼저 실행해주세요.

// Create customer
LOAD CSV WITH HEADERS FROM 'file:///customers.csv' AS row
MERGE (cust:Customer {customerID:row.CustomerID}) 
  ON CREATE SET cust.companyName = row.CompanyName, cust.contactName = row.ContactName, cust.contactTitle = row.ContactTitle, cust.address = row.Address, cust.city = row.City, cust.country = row.Country, cust.phone = row.Phone;
// Create relationships between orders and customers
LOAD CSV WITH HEADERS FROM "file:///orders.csv" AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (cust:Customer {customerID: row.CustomerID})
MERGE (cust)-[:PURCHASED]->(order);

그럼 어떤 물건이 가장 많이 팔렸는지 알아볼까요? 그리고 그걸 어느 고객이 샀는지 회사명도 출력해보겠습니다.

MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:CONTAINS]->(p:Product)
RETURN c.companyName, p.productName, count(o) AS orders
ORDER BY orders DESC
LIMIT 5;

다음은 DB 내에서 작동하는 Contents-based recommendation 시스템을 실행시키는 쿼리문입니다. 엄밀히 말하면 DB에 쌓인 주문한 상품의 쌍(동일한 카테고리) 데이터를 정렬해서 상위 5개만 보여주는 것이니 item-based recommendation이라고 할 수 있겠네요. 

has_also_purchased: 다른 고객이 customerID='ANTON'가 산 상품과 함께 샀던 상품 
MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:CONTAINS]->(p:Product)
<-[:CONTAINS]-(o2:Order)-[:CONTAINS]->(p2:Product)-[:PART_OF]->(:Category)<-[:PART_OF]-(p)
WHERE c.customerID = 'ANTON' and NOT( (c)-[:PURCHASED]->(:Order)-[:CONTAINS]->(p2) )
RETURN c.companyName, p.productName AS has_purchased, p2.productName AS has_also_purchased, count(DISTINCT o2) AS occurrences
ORDER BY occurrences DESC
LIMIT 5;

지금까지 사용한 쿼리 코드는 모두 Neo4j 공식 홈페이지에서 참고했습니다. 

728x90
반응형