Neo4j와 Spring Boot 시작하기
Neo4j와 Spring Boot로 소셜 네트워크 만들기
Neo4j와 Spring Boot 시작하기
Neo4j는 연결된 데이터를 다루는 데 특화된 그래프 데이터베이스다. Spring Data Neo4j는 Spring Boot와 자연스럽게 통합되어, 익숙한 Spring 패턴으로 그래프 데이터를 다룰 수 있게 해준다.
1. 의존성
pom.xml에 Spring Data Neo4j 스타터를 추가한다:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>Gradle의 경우:
implementation 'org.springframework.boot:spring-boot-starter-data-neo4j'2. 설정
application.yml에서 연결을 설정한다:
spring:
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: your-password로컬 개발 환경에서는 Docker로 Neo4j를 실행할 수 있다:
docker run -d \
--name neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/your-password \
neo4j:57474 포트는 브라우저 인터페이스, 7687은 Bolt 프로토콜 연결용이다.
3. 노드 정의
@Node로 엔티티 클래스를 만든다:
@Node
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
@Relationship(type = "FRIEND_OF", direction = Direction.OUTGOING)
private List<Person> friends = new ArrayList<>();
// constructors, getters, setters
}@Relationship 어노테이션은 그래프의 엣지를 정의한다. 방향이 중요한데, OUTGOING은 이 사람이 친구를 가지고 있음을, INCOMING은 다른 사람들이 이 사람을 친구로 여긴다는 것을 의미한다.
4. Repository
Spring Data Neo4j repository는 JPA repository와 동일하게 동작한다:
public interface PersonRepository extends Neo4jRepository<Person, Long> {
Optional<Person> findByName(String name);
@Query("MATCH (p:Person)-[:FRIEND_OF]->(f:Person) WHERE p.name = $name RETURN f")
List<Person> findFriendsOf(String name);
}메서드 이름 기반 쿼리가 기본으로 동작한다. 복잡한 탐색에는 @Query와 Cypher를 사용한다.
5. 기본 Cypher 쿼리
Cypher는 Neo4j의 쿼리 언어다. 필수 패턴 몇 가지:
노드 생성:
CREATE (p:Person {name: 'Alice', age: 30})관계 생성:
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
CREATE (a)-[:FRIEND_OF]->(b)친구의 친구 찾기:
MATCH (p:Person {name: 'Alice'})-[:FRIEND_OF]->()-[:FRIEND_OF]->(fof)
WHERE fof <> p
RETURN DISTINCT fof.name화살표 문법 ()-[]->() 는 탐색 방향을 나타낸다. 가변 길이 경로는 *를 사용한다: [:FRIEND_OF*2]는 정확히 2홉을 의미한다.
6. Service 계층
@Service
@Transactional
public class PersonService {
private final PersonRepository repository;
public PersonService(PersonRepository repository) {
this.repository = repository;
}
public Person create(String name, int age) {
Person person = new Person(name, age);
return repository.save(person);
}
public void addFriend(String personName, String friendName) {
Person person = repository.findByName(personName)
.orElseThrow(() -> new RuntimeException("Person not found"));
Person friend = repository.findByName(friendName)
.orElseThrow(() -> new RuntimeException("Friend not found"));
person.getFriends().add(friend);
repository.save(person);
}
public List<Person> getFriends(String name) {
return repository.findFriendsOf(name);
}
}@Transactional 어노테이션은 관계 수정이 원자적으로 이루어지도록 보장한다.
7. Neo4j를 사용해야 할 때
그래프 데이터베이스가 빛을 발하는 경우:
- 소셜 네트워크 (친구, 팔로워, 연결)
- 추천 엔진 (X를 산 사용자가 Y도 구매함)
- 사기 탐지 (거래에서 의심스러운 패턴 찾기)
- 지식 그래프와 계층 구조
복잡한 관계 없이 단순 CRUD만 필요하다면 관계형 데이터베이스가 더 간단하다. Neo4j는 여러 단계의 관계를 탐색하는 쿼리가 필요할 때 가치를 발휘한다.
8. 결론
Spring Data Neo4j는 Neo4j에 대한 깔끔한 추상화를 제공한다. @Node로 노드를, @Relationship으로 관계를 정의하고, repository로 기본 작업을 처리한다. 복잡한 그래프 탐색에는 Cypher 쿼리가 완전한 제어권을 제공한다.