Neo4j 벡터 스토어
Neo4j 벡터 스토어 (Neo4j Vector Store)
이 섹션에서는 Neo4jVectorStore를 설정해서 문서 임베딩을 저장하고 유사도 검색을 수행하는 방법을 안내해요. Neo4j는 관계로 연결된 노드로 구성된 그래프 구조의 데이터를 저장하는 오픈소스 NoSQL 그래프 데이터베이스예요. Neo4j의 Vector Search는 대규모 데이터셋의 벡터 임베딩을 질의할 수 있게 해 줘요.
출처: 문서
본문
Neo4j
이 섹션은 Neo4jVectorStore를 설정해 문서 임베딩을 저장하고 유사도 검색을 수행하는 방법을 안내해요.
Neo4j는 오픈소스 NoSQL 그래프 데이터베이스예요. 관계로 연결된 노드로 구성된 그래프로 구조화된 데이터를 저장하는 완전 트랜잭션 데이터베이스(ACID)예요. 실제 세계의 구조에서 영감을 받아 복잡한 데이터에 대해 높은 쿼리 성능을 제공하면서도 개발자에게 직관적이고 단순해요.
Neo4j의 Vector Search는 사용자가 대규모 데이터셋의 벡터 임베딩을 질의할 수 있게 해 줘요. 임베딩은 텍스트, 이미지, 오디오, 문서 같은 데이터 객체의 수치 표현이에요. 임베딩은 Node 속성에 저장할 수 있고 db.index.vector.queryNodes() 함수로 질의할 수 있어요. 이런 인덱스는 Lucene이 구동하며 Hierarchical Navigable Small World Graph (HNSW)를 사용해 벡터 필드에 대한 k 근사 최근접 이웃(k-ANN) 질의를 수행해요.
사전 준비 (Prerequisites)
-
실행 중인 Neo4j (5.15+) 인스턴스. 다음 옵션이 가능해요:
- Docker 이미지
- Neo4j Desktop
- Neo4j Aura
- Neo4j Server 인스턴스
-
필요하다면,
Neo4jVectorStore가 저장하는 임베딩을 생성하기 위한 EmbeddingModel용 API 키.
자동 설정 (Auto-configuration)
참고: Spring AI auto-configuration과 starter 모듈의 아티팩트 이름에 큰 변화가 있었어요. 자세한 내용은 upgrade notes를 참고해 주세요.
Spring AI는 Neo4j Vector Store에 대한 Spring Boot 자동 설정을 제공해요. 활성화하려면 프로젝트의 Maven pom.xml 파일에 다음 의존성을 추가하세요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-neo4j</artifactId>
</dependency>
또는 Gradle build.gradle 빌드 파일에:
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-vector-store-neo4j'
}
참고: 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을 참고해 주세요.
기본값과 구성 옵션을 알려면 벡터 스토어의 구성 프로퍼티 목록을 살펴보세요.
참고: 빌드 파일에 Maven Central 및/또는 Snapshot 저장소를 추가하려면 Artifact Repositories 섹션을 참고해 주세요.
벡터 스토어 구현은 필요한 스키마를 초기화할 수 있지만, 적절한 생성자에서 initializeSchema boolean을 지정하거나 application.properties 파일에서 …initialize-schema=true를 설정해 선택해야 해요.
참고: 이것은 호환성을 깨는 변경이에요! 이전 버전의 Spring AI에서는 이 스키마 초기화가 기본으로 일어났어요.
추가로 구성된 EmbeddingModel 빈이 필요해요. 자세한 내용은 EmbeddingModel 섹션을 참고하세요.
이제 애플리케이션에서 Neo4jVectorStore를 벡터 스토어로 오토와이어할 수 있어요.
@Autowired VectorStore vectorStore;
// ...
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
new Document("The World is Big and Salvation Lurks Around the Corner"),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));
// Add the documents to Neo4j
vectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
구성 프로퍼티 (Configuration Properties)
Neo4j에 연결하고 Neo4jVectorStore를 사용하려면 인스턴스의 접근 세부 정보를 제공해야 해요. 간단한 구성은 Spring Boot의 application.yml로 제공할 수 있어요:
spring:
neo4j:
uri: <neo4j instance URI>
authentication:
username: <neo4j username>
password: <neo4j password>
ai:
vectorstore:
neo4j:
initialize-schema: true
database-name: neo4j
index-name: custom-index
embedding-dimension: 1536
distance-type: cosine
spring.neo4j.*로 시작하는 Spring Boot 프로퍼티는 Neo4j 클라이언트를 구성하는 데 사용돼요:
| Property | Description | Default Value |
|---|---|---|
spring.neo4j.uri |
Neo4j 인스턴스에 연결하기 위한 URI | neo4j://localhost:7687 |
spring.neo4j.authentication.username |
Neo4j 인증용 사용자 이름 | neo4j |
spring.neo4j.authentication.password |
Neo4j 인증용 비밀번호 | - |
spring.ai.vectorstore.neo4j.*로 시작하는 프로퍼티는 Neo4jVectorStore를 구성하는 데 사용돼요:
| Property | Description | Default Value |
|---|---|---|
spring.ai.vectorstore.neo4j.initialize-schema |
필요한 스키마를 초기화할지 여부 | false |
spring.ai.vectorstore.neo4j.database-name |
사용할 Neo4j 데이터베이스의 이름 | neo4j |
spring.ai.vectorstore.neo4j.index-name |
벡터를 저장할 인덱스의 이름 | spring-ai-document-index |
spring.ai.vectorstore.neo4j.embedding-dimension |
벡터의 차원 수 | 1536 |
spring.ai.vectorstore.neo4j.distance-type |
사용할 거리 함수 | cosine |
spring.ai.vectorstore.neo4j.label |
문서 노드에 사용되는 라벨 | Document |
spring.ai.vectorstore.neo4j.embedding-property |
임베딩을 저장하는 데 사용되는 프로퍼티 이름 | embedding |
다음 거리 함수를 사용할 수 있어요:
cosine- 기본값, 대부분의 사용 사례에 적합. 벡터 간 코사인 유사도를 측정.euclidean- 벡터 간 유클리드 거리. 값이 낮을수록 유사도가 높음.
수동 구성 (Manual Configuration)
Spring Boot 자동 설정 대신 Neo4j 벡터 스토어를 수동 구성할 수 있어요. 이를 위해 프로젝트에 spring-ai-neo4j-store를 추가해야 해요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-neo4j-store</artifactId>
</dependency>
또는 Gradle build.gradle 빌드 파일에:
dependencies {
implementation 'org.springframework.ai:spring-ai-neo4j-store'
}
참고: 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을 참고해 주세요.
Neo4j Driver 빈을 만드세요. 커스텀 드라이버 구성에 대한 더 깊이 있는 정보는 Neo4j Documentation을 읽어보세요.
@Bean
public Driver driver() {
return GraphDatabase.driver("neo4j://<host>:<bolt-port>",
AuthTokens.basic("<username>", "<password>"));
}
그런 다음 빌더 패턴으로 Neo4jVectorStore 빈을 만드세요:
@Bean
public VectorStore vectorStore(Driver driver, EmbeddingModel embeddingModel) {
return Neo4jVectorStore.builder(driver, embeddingModel)
.databaseName("neo4j") // Optional: defaults to "neo4j"
.distanceType(Neo4jDistanceType.COSINE) // Optional: defaults to COSINE
.embeddingDimension(1536) // Optional: defaults to 1536
.label("Document") // Optional: defaults to "Document"
.embeddingProperty("embedding") // Optional: defaults to "embedding"
.indexName("custom-index") // Optional: defaults to "spring-ai-document-index"
.initializeSchema(true) // Optional: defaults to false
.batchingStrategy(new TokenCountBatchingStrategy()) // Optional: defaults to TokenCountBatchingStrategy
.build();
}
// This can be any EmbeddingModel implementation
@Bean
public EmbeddingModel embeddingModel() {
return new OpenAiEmbeddingModel(OpenAiEmbeddingOptions.builder().apiKey(System.getenv("OPENAI_API_KEY")).build());
}
메타데이터 필터링 (Metadata Filtering)
Neo4j 스토어에서도 일반적이고 휴대 가능한 메타데이터 필터를 활용할 수 있어요.
예를 들어 텍스트 표현 언어를 사용할 수 있어요:
vectorStore.similaritySearch(
SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'").build());
또는 Filter.Expression DSL로 프로그래밍 방식으로:
FilterExpressionBuilder b = new FilterExpressionBuilder();
vectorStore.similaritySearch(SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression(b.and(
b.in("author", "john", "jill"),
b.eq("article_type", "blog")).build()).build());
참고: 이 (휴대 가능한) 필터 표현식은 자동으로 고유한 Neo4j
WHERE필터 표현식으로 변환돼요.
예를 들어 이 휴대 가능한 필터 표현식:
author in ['john', 'jill'] && 'article_type' == 'blog'
은 고유한 Neo4j 필터 형식으로 변환돼요:
node.`metadata.author` IN ["john","jill"] AND node.`metadata.'article_type'` = "blog"
네이티브 클라이언트 접근 (Accessing the Native Client)
Neo4j Vector Store 구현은 getNativeClient() 메서드를 통해 내부 네이티브 Neo4j 클라이언트(Driver)에 접근을 제공해요:
Neo4jVectorStore vectorStore = context.getBean(Neo4jVectorStore.class);
Optional<Driver> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Driver driver = nativeClient.get();
// Use the native client for Neo4j-specific operations
}
네이티브 클라이언트는 VectorStore 인터페이스로는 노출되지 않는 Neo4j 특화 기능과 작업에 접근할 수 있게 해 줘요.