https://neo4j.com/docs/getting-started/data-modeling/tutorial-refactoring/
데이터 모델과 그래프를 바꾸는 과정
그 이유로는:
CREATE (Apollo13:Movie {title: 'Apollo 13', tmdbID: 568, released: '1995-06-30', imdbRating: 7.6, genres: ['Drama', 'Adventure', 'IMAX']})
CREATE (TomH:Person {name: 'Tom Hanks', tmdbID: 31, born: '1956-07-09'})
CREATE (MegR:Person {name: 'Meg Ryan', tmdbID: 5344, born: '1961-11-19'})
CREATE (DannyD:Person {name: 'Danny DeVito', tmdbID: 518, born: '1944-11-17'})
CREATE (JackN:Person {name: 'Jack Nicholson', tmdbID: 514, born: '1937-04-22'})
CREATE (SleeplessInSeattle:Movie {title: 'Sleepless in Seattle', tmdbID: 858, released: '1993-06-25', imdbRating: 6.8, genres: ['Comedy', 'Drama', 'Romance']})
CREATE (Hoffa:Movie {title: 'Hoffa', tmdbID: 10410, released: '1992-12-25', imdbRating: 6.6, genres: ['Crime', 'Drama']})
MERGE (TomH)-[:ACTED_IN {roles:'Jim Lovell'}]->(Apollo13)
MERGE (TomH)-[:ACTED_IN {roles:'Sam Baldwin'}]->(SleeplessInSeattle)
MERGE (MegR)-[:ACTED_IN {roles:'Annie Reed'}]->(SleeplessInSeattle)
MERGE (DannyD)-[:DIRECTED]->(Hoffa)
MERGE (DannyD)-[:ACTED_IN {roles:'Robert "Bobby" Ciaro'}]->(Hoffa)
MERGE (JackN)-[:ACTED_IN {roles:'Hoffa'}]->(Hoffa)
CREATE (Sandy:User {name: 'Sandy Jones', userID: 1})
CREATE (Clinton:User {name: 'Clinton Spencer', userID: 2})
MERGE (Sandy)-[:RATED {rating:5}]->(Apollo13)
MERGE (Sandy)-[:RATED {rating:4}]->(SleeplessInSeattle)
MERGE (Clinton)-[:RATED {rating:3}]->(Apollo13)
MERGE (Clinton)-[:RATED {rating:3}]->(SleeplessInSeattle)
MERGE (Clinton)-[:RATED {rating:3}]->(Hoffa)
MATCH (Apollo13:Movie {title:'Apollo 13'})
MATCH (SleeplessInSeattle:Movie {title:'Sleepless in Seattle'})
MATCH (Hoffa:Movie {title:'Hoffa'})
SET Apollo13.languages = ['English']
SET SleeplessInSeattle.languages = ['English']
SET Hoffa.languages = ['English', 'Italian', 'Latin']

MATCH (m:Movie)
WHERE 'English' IN m.languages
RETURN m.title
위의 쿼리는 모든 영화 노드를 체크하여 언어 프로퍼티가 영어인지 확인한다. 이는 틀린 것은 아니지만, 두 가지 이슈가 있을 수 있다:
언어 프로퍼티를 리팩토링 하고 영화 노드에 새로운 관계로 연결하는 것으로 해결할 수 있다.

MATCH (m:Movie)
WITH m, m.languages AS languages
UNWIND languages AS language
MERGE (l:Language {name: language})
MERGE (m)-[:IN_LANGUAGE]->(l)
REMOVE m.languages
실행하면 아래와 같이 됨:

만약 각 영화의 프로듀서에 대한 새로운 유즈 케이스가 필요하게 되었다고 할 때, 프로듀서의 실제 주소를 포함한 프로듀서에 대한 데이터는 복잡한 데이터라고 볼 수있다.
이러한 정보를 Productioncompany라는 노드에 주소 프로퍼티와 함께 그래프에 추가할 수 있다.
CREATE (p:ProductionCompany {name:'Imagine Entertainment', country:'US', postalCode:90212, state:'CA', city:'Beverly Hills', address1:'10351 Santa Monica Blvd'})
MERGE (Apollo13:Movie {title:'Apollo 13'})
CREATE (p)-[:PRODUCED]->(Apollo13)
CREATE (jerseyFilms:ProductionCompany {name:'Jersey Films', country:'US', postalCode:90049, state:'CA', city:'Los Angeles', address1:'10351 Santa Monica Blvd'})
MERGE (hoffa:Movie {title:'Hoffa'})
CREATE (jerseyFilms)-[:PRODUCED]->(hoffa)
그러나 이렇게 데이터를 저장하는 것은 몇가지 부분에서 좋지 않을 수 있다:
데이터 모델링에 있어서의 목표는 쿼리로 체크해야 하는 그래프의 사이즈를 줄이는 데 있다.
위의 예에서는 두 개의 회사가 캘리포니아에 있으므로 주를 다른 노드로서 추가할 수 있을 것이다.
또 다른 예로서 1995년에 영화에 출연한 배우를 빈번히 조회해야 한다면 ACTED_IN_1995라는 지정된 관계를 만들게 되면 이 특정 관계를 찾아 조회하면 되므로 불필요한 체크를 피할 수 있어 쿼리의 효율을 높일 수 있다.
리팩토링이 끝난 후에는 모든 유즈 케이즈의 쿼리를 체크하여 모두 원활하게 작동하는지 체크하고, 업데이트 되야할 쿼리문이 있다면 업데이트를 해준다.
만약 리팩토링 후 쿼리문의 성능이 올라갔는지 보기 위해서는 쿼리문을 실행했을 때 검색되는 요소들의 수를 체크해 볼 수 있다.