벡터 임베딩을 만드는 방법
이 페이지의 내용
벡터 임베딩을 다른 데이터와 함께 Atlas에 저장할 수 있습니다. 이러한 임베딩은 데이터 내의 의미 있는 관계를 포착하여 Atlas Vector Search에서 시맨틱 검색을 수행하고 RAG를 구현할 수 있도록 합니다.
시작하기
다음 튜토리얼을 통해 Atlas Vector Search 를 사용하여 벡터 임베딩을 만들고 쿼리 하는 방법을 학습 보세요. 구체적으로 다음 조치를 수행합니다.
임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다.
데이터에서 임베딩을 생성하여 Atlas에 저장합니다.
검색어에서 임베딩을 생성하고 벡터 검색 쿼리를 실행합니다.
프로덕션 애플리케이션의 경우 일반적으로 벡터 임베딩을 생성하는 스크립트 를 쓰기 (write) 합니다. 이 페이지의 샘플 코드로 시작하여 사용 사례 에 맞게 사용자 지정할 수 있습니다.
➤ 언어 선택 드롭다운 메뉴를 사용하여 이 페이지에 있는 예시의 언어를 설정합니다.
전제 조건
이 튜토리얼을 완료하려면 다음 조건을 충족해야 합니다.
MongoDB 버전 6.0.11 7.0.2이상(RC 포함)을 실행 하는 클러스터 가 있는 Atlas 계정. 사용자의 IP 주소 가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 학습 내용은 클러스터 생성을 참조하세요.
C# 프로젝트 실행 위한 터미널 및 코드 편집기입니다.
.NET 8.0 이상이 설치되어 있어야 합니다.
Hugging Face Access Token 또는 OpenAI API 키입니다.
MongoDB 버전 6.0.11, 7.0.2 이상(RC 포함)을 실행 하는 클러스터 가 있는 Atlas 계정. 사용자의 IP 주소 가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 학습 내용은 클러스터 생성을 참조하세요.
Go 프로젝트를 실행하기 위한 터미널 및 코드 편집기입니다.
Go가 설치되었습니다.
Hugging Face Access Token 또는 OpenAI API 키입니다.
MongoDB 버전 6.0.11, 7.0.2 이상(RC 포함)을 실행 하는 클러스터 가 있는 Atlas 계정. 사용자의 IP 주소 가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 학습 내용은 클러스터 생성을 참조하세요.
Java Development Kit (JDK) 버전 8 이상.
Java 애플리케이션 을 설정하다 하고 실행 하기 위한 환경입니다.IntelliJ IDEA 또는 Eclipse IDE와 같은 통합 개발 환경(IDE)을 사용하여 프로젝트 를 빌드 하고 실행 하도록 Maven 또는 Gradle을 구성하는 것이 좋습니다.
다음 중 하나입니다.
읽기 액세스 이 있는 Hugging face 액세스 토큰
OpenAI API 키. API 요청에 사용할 수 있는 크레딧이 있는 유료 OpenAI 계정이 있어야 합니다. OpenAI 계정 등록에 대한 자세한 내용은 OpenAI API 웹사이트를 참조하세요.
MongoDB 버전 6.0.11, 7.0.2 이상(RC 포함)을 실행 하는 클러스터 가 있는 Atlas 계정. 사용자의 IP 주소 가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 학습 내용은 클러스터 생성을 참조하세요.
Node.js 프로젝트를 실행하기 위한 터미널 및 코드 편집기입니다.
npm 및 Node.js 설치되었습니다.
OpenAI 모델을 사용하는 경우 OpenAI API 키가 있어야 합니다.
MongoDB 버전 6.0.11, 7.0.2 이상(RC 포함)을 실행 하는 클러스터 가 있는 Atlas 계정. 사용자의 IP 주소 가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 학습 내용은 클러스터 생성을 참조하세요.
OpenAI 모델을 사용하는 경우 OpenAI API 키가 있어야 합니다.
임베딩 함수 정의하기
환경 변수를 설정합니다.
환경 변수를 내보내거나, PowerShell에서 set
하거나, IDE의 환경 변수 관리자를 사용하여 프로젝트 에서 연결 문자열 과 HuggingFace 액세스 토큰을 사용할 수 있도록 합니다.
export HUGGINGFACE_ACCESS_TOKEN="<access-token>" export ATLAS_CONNECTION_STRING="<connection-string>"
<access-token>
자리 표시자 값을 허깅 페이스 액세스 토큰으로 바꿉니다.
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 함수를 정의합니다.
이름이 같은 이름의 파일 에 새 클래스를 AIService.cs
만들고 다음 코드를 붙여넣습니다. 이 코드는 GetEmbeddingsAsync
지정된 문자열 입력 배열 에 대한 임베딩 배열 을 생성하기 위해 라는 이름의 비동기 작업을 정의합니다. 이 함수는 mxbai-embed-large-v1 임베딩 모델을 사용합니다.
namespace MyCompany.Embeddings; using System; using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; using System.Net.Http.Headers; public class AIService { private static readonly string? HuggingFaceAccessToken = Environment.GetEnvironmentVariable("HUGGINGFACE_ACCESS_TOKEN"); private static readonly HttpClient Client = new HttpClient(); public async Task<Dictionary<string, float[]>> GetEmbeddingsAsync(string[] texts) { const string modelName = "mixedbread-ai/mxbai-embed-large-v1"; const string url = $"https://api-inference.huggingface.co/models/{modelName}"; Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HuggingFaceAccessToken); var data = new { inputs = texts }; var dataJson = JsonSerializer.Serialize(data); var content = new StringContent(dataJson,null, "application/json"); var response = await Client.PostAsync(url, content); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); var embeddings = JsonSerializer.Deserialize<float[][]>(responseString); if (embeddings is null) { throw new ApplicationException("Failed to deserialize embeddings response to an array of floats."); } Dictionary<string, float[]> documentData = new Dictionary<string, float[]>(); var embeddingCount = embeddings.Length; foreach (var value in Enumerable.Range(0, embeddingCount)) { // Pair each embedding with the text used to generate it. documentData[texts[value]] = embeddings[value]; } return documentData; } }
참고
허깅 페이스 모델을 호출할 때 503
Hugging Face 모델 허브 모델을 호출할 때 503 오류가 발생할 수 있습니다. 이 문제를 해결하려면 잠시 후 다시 시도하세요.
환경 변수를 설정합니다.
환경 변수를 내보내거나, PowerShell에서 set
하거나, IDE의 환경 변수 관리자를 사용하여 프로젝트 에서 연결 문자열 과 HuggingFace 액세스 토큰을 사용할 수 있도록 합니다.
export OPENAI_API_KEY="<api-key>" export ATLAS_CONNECTION_STRING="<connection-string>"
<api-key>
자리 표시자 값을 OpenAI API 키로 바꿉니다.
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 함수를 정의합니다.
이름이 같은 이름의 파일 AIService.cs
에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 지정된 문자열 입력 배열 에 대한 임베딩 배열 을 생성하기 위해 GetEmbeddingsAsync
라는 이름의 비동기 작업을 정의합니다. 이 함수는 OpenAI의 text-embedding-3-small
모델을 사용하여 주어진 입력에 대한 임베딩을 생성합니다.
namespace MyCompany.Embeddings; using OpenAI.Embeddings; using System; using System.Threading.Tasks; public class AIService { private static readonly string? OpenAIApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); private static readonly string EmbeddingModelName = "text-embedding-3-small"; public async Task<Dictionary<string, float[]>> GetEmbeddingsAsync(string[] texts) { EmbeddingClient embeddingClient = new(model: EmbeddingModelName, apiKey: OpenAIApiKey); Dictionary<string, float[]> documentData = new Dictionary<string, float[]>(); try { var result = await embeddingClient.GenerateEmbeddingsAsync(texts); var embeddingCount = result.Value.Count; foreach (var index in Enumerable.Range(0, embeddingCount)) { // Pair each embedding with the text used to generate it. documentData[texts[index]] = result.Value[index].ToFloats().ToArray(); } } catch (Exception e) { throw new ApplicationException(e.Message); } return documentData; } }
이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI와 같은 독점 모델을 사용할지에 따라 탭 선택하세요.
참고
오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.
파일 을 생성하여 .env
시크릿을 관리 합니다.
프로젝트에서 Atlas 연결 문자열과 Hugging Face 액세스 토큰을 저장할 .env
파일을 생성하세요.
HUGGINGFACEHUB_API_TOKEN = "<access-token>" ATLAS_CONNECTION_STRING = "<connection-string>"
<access-token>
자리 표시자 값을 허깅 페이스 액세스 토큰으로 바꿉니다.
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 함수를 정의합니다.
프로젝트에
common
디렉토리를 만들어 이후 단계에서 사용할 일반 코드를 저장합니다.mkdir common && cd common get-embeddings.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 주어진 입력에 대한 임베딩을 생성하는GetEmbeddings
함수를 정의합니다. 이 기능은 다음을 지정합니다.LangChain 라이브러리의
feature-extraction
Go 포트를 사용하는 작업. 자세한 내용은 LangChain JavaScript 문서에서 작업 문서를 참조하세요.mxbai-embed-large-v1 임베딩 모델.
get-embeddings.gopackage common import ( "context" "log" "github.com/tmc/langchaingo/embeddings/huggingface" ) func GetEmbeddings(documents []string) [][]float32 { hf, err := huggingface.NewHuggingface( huggingface.WithModel("mixedbread-ai/mxbai-embed-large-v1"), huggingface.WithTask("feature-extraction")) if err != nil { log.Fatalf("failed to connect to Hugging Face: %v", err) } embs, err := hf.EmbedDocuments(context.Background(), documents) if err != nil { log.Fatalf("failed to generate embeddings: %v", err) } return embs } 참고
허깅 페이스 모델을 호출할 때 503
Hugging Face 모델 허브 모델을 호출할 때 503 오류가 발생할 수 있습니다. 이 문제를 해결하려면 잠시 후 다시 시도하세요.
메인 프로젝트 루트 디렉토리로 다시 이동합니다.
cd ../
파일 을 생성하여 .env
시크릿을 관리 합니다.
.env
프로젝트 string 에서 연결 문자열 과 OpenAI API API 토큰을 저장 파일 을 만듭니다.
OPENAI_API_KEY = "<api-key>" ATLAS_CONNECTION_STRING = "<connection-string>"
<api-key>
및 <connection-string>
자리 표시자 값을 OpenAI API 키와 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다. 연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
참고
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 함수를 정의합니다.
프로젝트 에
common
라는 디렉토리 를 만들어 여러 단계에서 사용할 코드를 저장 합니다.mkdir common && cd common get-embeddings.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 OpenAI의text-embedding-3-small
모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는GetEmbeddings
함수를 정의합니다.get-embeddings.gopackage common import ( "context" "log" "github.com/milosgajdos/go-embeddings/openai" ) func GetEmbeddings(docs []string) [][]float64 { c := openai.NewClient() embReq := &openai.EmbeddingRequest{ Input: docs, Model: openai.TextSmallV3, EncodingFormat: openai.EncodingFloat, } embs, err := c.Embed(context.Background(), embReq) if err != nil { log.Fatalf("failed to connect to OpenAI: %v", err) } var vectors [][]float64 for _, emb := range embs { vectors = append(vectors, emb.Vector) } return vectors } 메인 프로젝트 루트 디렉토리로 다시 이동합니다.
cd ../
이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI와 같은 독점 모델을 사용할지에 따라 탭 선택하세요.
참고
오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.
Java 프로젝트 를 생성하고 종속성을 설치합니다.
IDE에서 Maven 또는 Gradle을 사용하여 Java 프로젝트 를 만듭니다.
패키지 관리자에 따라 다음 종속성을 추가합니다.
Maven을 사용하는 경우 프로젝트의
pom.xml
파일 에 있는dependencies
배열 에 다음 종속성을 추가합니다.pom.xml<dependencies> <!-- MongoDB Java Sync Driver v5.2.0 or later --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>[5.2.0,)</version> </dependency> <!-- Java library for working with Hugging Face models --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-hugging-face</artifactId> <version>0.35.0</version> </dependency> </dependencies> Gradle을 사용하는 경우 프로젝트의
build.gradle
파일 에 있는dependencies
배열 에 다음을 추가합니다.build.gradledependencies { // MongoDB Java Sync Driver v5.2.0 or later implementation 'org.mongodb:mongodb-driver-sync:[5.2.0,)' // Java library for working with Hugging Face models implementation 'dev.langchain4j:langchain4j-hugging-face:0.35.0' } 패키지 관리자를 실행하여 프로젝트 에 종속성을 설치합니다.
환경 변수를 설정합니다.
참고
이 예시 에서는 IDE에서 프로젝트 에 대한 변수를 설정합니다. 프로덕션 애플리케이션은 배포서버 구성, CI/CD 파이프라인 또는 시크릿 관리자를 통해 환경 변수를 관리 할 수 있지만, 제공된 코드를 사용 사례 에 맞게 조정할 수 있습니다.
IDE에서 새 구성 템플릿을 만들고 프로젝트 에 다음 변수를 추가합니다.
IntelliJ IDEA를 사용하는 경우 새 Application 실행 구성 템플릿을 만든 다음 Environment variables 필드 에 변수를 세미콜론으로 구분된 값으로 추가합니다( 예시:
FOO=123;BAR=456
). 변경 사항을 적용하고 OK를 클릭합니다.학습 내용은 IntelliJ IDEA 문서의 템플릿에서 실행/디버그 구성 만들기 섹션을 참조하세요.
Eclipse를 사용하는 경우 새 Java Application 시작 구성을 만든 다음 Environment 탭 에서 각 변수를 새 키-값 쌍으로 추가합니다. 변경 사항을 적용하고 OK를 클릭합니다.
학습 내용은 Eclipse IDE 문서의 Java 애플리케이션 실행 구성 생성하기 섹션을 참조하세요.
HUGGING_FACE_ACCESS_TOKEN=<access-token> ATLAS_CONNECTION_STRING=<connection-string>
다음 값으로 자리 표시자를 업데이트합니다.
``<access-token>`` 자리 표시자 값을 허깅 페이스 액세스 토큰으로 바꿉니다.
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 메서드를 정의합니다.
EmbeddingProvider.java
이라는 파일을 만들고 다음 코드를 붙여넣습니다.
이 코드는 mxbai-embed-large-v1 오픈 소스 임베딩 모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는 두 가지 메서드를 정의합니다.
다중 입력 :
getEmbeddings
메서드는 텍스트 입력 배열 (List<String>
)을 허용하므로 단일 API 호출로 여러 임베딩을 생성할 수 있습니다. 이 메서드는 Atlas cluster 에 저장하기 위해 API 에서 제공하는 float 배열을 double 의 BSON 배열로 변환합니다.단일 입력: 메서드는
getEmbedding
String
벡터 데이터에 대해 수행하려는 쿼리 를 나타내는 단일 을 허용합니다. 이 메서드는 컬렉션 을 쿼리할 때 사용할 수 있도록 API 에서 제공하는 부동 소수점 배열 을 double의 BSON 배열 로 변환합니다.
import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.huggingface.HuggingFaceEmbeddingModel; import dev.langchain4j.model.output.Response; import org.bson.BsonArray; import org.bson.BsonDouble; import java.util.List; import static java.time.Duration.ofSeconds; public class EmbeddingProvider { private static HuggingFaceEmbeddingModel embeddingModel; private static HuggingFaceEmbeddingModel getEmbeddingModel() { if (embeddingModel == null) { String accessToken = System.getenv("HUGGING_FACE_ACCESS_TOKEN"); if (accessToken == null || accessToken.isEmpty()) { throw new RuntimeException("HUGGING_FACE_ACCESS_TOKEN env variable is not set or is empty."); } embeddingModel = HuggingFaceEmbeddingModel.builder() .accessToken(accessToken) .modelId("mixedbread-ai/mxbai-embed-large-v1") .waitForModel(true) .timeout(ofSeconds(60)) .build(); } return embeddingModel; } /** * Takes an array of strings and returns a BSON array of embeddings to * store in the database. */ public List<BsonArray> getEmbeddings(List<String> texts) { List<TextSegment> textSegments = texts.stream() .map(TextSegment::from) .toList(); Response<List<Embedding>> response = getEmbeddingModel().embedAll(textSegments); return response.content().stream() .map(e -> new BsonArray( e.vectorAsList().stream() .map(BsonDouble::new) .toList())) .toList(); } /** * Takes a single string and returns a BSON array embedding to * use in a vector query. */ public BsonArray getEmbedding(String text) { Response<Embedding> response = getEmbeddingModel().embed(text); return new BsonArray( response.content().vectorAsList().stream() .map(BsonDouble::new) .toList()); } }
Java 프로젝트 를 생성하고 종속성을 설치합니다.
IDE에서 Maven 또는 Gradle을 사용하여 Java 프로젝트 를 만듭니다.
패키지 관리자에 따라 다음 종속성을 추가합니다.
Maven을 사용하는 경우 프로젝트의
pom.xml
파일 에 있는dependencies
배열 에 다음 종속성을 추가합니다.pom.xml<dependencies> <!-- MongoDB Java Sync Driver v5.2.0 or later --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>[5.2.0,)</version> </dependency> <!-- Java library for working with OpenAI models --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>0.35.0</version> </dependency> </dependencies> Gradle을 사용하는 경우 프로젝트의
build.gradle
파일 에 있는dependencies
배열 에 다음을 추가합니다.build.gradledependencies { // MongoDB Java Sync Driver v5.2.0 or later implementation 'org.mongodb:mongodb-driver-sync:[5.2.0,)' // Java library for working with OpenAI models implementation 'dev.langchain4j:langchain4j-open-ai:0.35.0' } 패키지 관리자를 실행하여 프로젝트 에 종속성을 설치합니다.
환경 변수를 설정합니다.
참고
이 예시 에서는 IDE에서 프로젝트 에 대한 변수를 설정합니다. 프로덕션 애플리케이션은 배포서버 구성, CI/CD 파이프라인 또는 시크릿 관리자를 통해 환경 변수를 관리 할 수 있지만, 제공된 코드를 사용 사례 에 맞게 조정할 수 있습니다.
IDE에서 새 구성 템플릿을 만들고 프로젝트 에 다음 변수를 추가합니다.
IntelliJ IDEA를 사용하는 경우 새 Application 실행 구성 템플릿을 만든 다음 Environment variables 필드 에 변수를 세미콜론으로 구분된 값으로 추가합니다( 예시:
FOO=123;BAR=456
). 변경 사항을 적용하고 OK 을 클릭합니다.학습 내용은 IntelliJ IDEA 문서의 템플릿에서 실행/디버그 구성 만들기 섹션을 참조하세요.
Eclipse를 사용하는 경우 새 Java Application 시작 구성을 만든 다음 Environment 탭 에서 각 변수를 새 키-값 쌍으로 추가합니다. 변경 사항을 적용하고 OK를 클릭합니다.
학습 내용은 Eclipse IDE 문서의 Java 애플리케이션 실행 구성 생성하기 섹션을 참조하세요.
OPEN_AI_API_KEY=<api-key> ATLAS_CONNECTION_STRING=<connection-string>
다음 값으로 자리 표시자를 업데이트합니다.
``<api-key>`` 자리 표시자 값을 OpenAI API 키로 바꿉니다.
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
벡터 임베딩을 생성하는 메서드를 정의합니다.
EmbeddingProvider.java
이라는 파일을 만들고 다음 코드를 붙여넣습니다.
이 코드는 text-embedding- -small3 OpenAI 임베딩 모델을 사용하여 주어진 입력에 대한 임베딩을 생성하는 두 가지 메서드를 정의합니다.
다중 입력 :
getEmbeddings
메서드는 텍스트 입력 배열 (List<String>
)을 허용하므로 단일 API 호출로 여러 임베딩을 생성할 수 있습니다. 이 메서드는 Atlas cluster 에 저장하기 위해 API 에서 제공하는 float 배열을 double 의 BSON 배열로 변환합니다.단일 입력: 메서드는
getEmbedding
String
벡터 데이터에 대해 수행하려는 쿼리 를 나타내는 단일 을 허용합니다. 이 메서드는 컬렉션 을 쿼리할 때 사용할 수 있도록 API 에서 제공하는 부동 소수점 배열 을 double의 BSON 배열 로 변환합니다.
import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.openai.OpenAiEmbeddingModel; import dev.langchain4j.model.output.Response; import org.bson.BsonArray; import org.bson.BsonDouble; import java.util.List; import static java.time.Duration.ofSeconds; public class EmbeddingProvider { private static OpenAiEmbeddingModel embeddingModel; private static OpenAiEmbeddingModel getEmbeddingModel() { if (embeddingModel == null) { String apiKey = System.getenv("OPEN_AI_API_KEY"); if (apiKey == null || apiKey.isEmpty()) { throw new IllegalStateException("OPEN_AI_API_KEY env variable is not set or is empty."); } return OpenAiEmbeddingModel.builder() .apiKey(apiKey) .modelName("text-embedding-3-small") .timeout(ofSeconds(60)) .build(); } return embeddingModel; } /** * Takes an array of strings and returns a BSON array of embeddings to * store in the database. */ public List<BsonArray> getEmbeddings(List<String> texts) { List<TextSegment> textSegments = texts.stream() .map(TextSegment::from) .toList(); Response<List<Embedding>> response = getEmbeddingModel().embedAll(textSegments); return response.content().stream() .map(e -> new BsonArray( e.vectorAsList().stream() .map(BsonDouble::new) .toList())) .toList(); } /** * Takes a single string and returns a BSON array embedding to * use in a vector query. */ public BsonArray getEmbedding(String text) { Response<Embedding> response = getEmbeddingModel().embed(text); return new BsonArray( response.content().vectorAsList().stream() .map(BsonDouble::new) .toList()); } }
이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI와 같은 독점 모델을 사용할지에 따라 탭 선택하세요.
참고
오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.
package.json
파일을 업데이트합니다.
ES 모듈을 사용하도록 프로젝트를 설정하려면 package.json
파일에 "type": "module"
을 추가한 후 저장합니다.
{ "type": "module", // other fields... }
.env
파일을 만듭니다.
프로젝트에서 Atlas 연결 문자열을 저장할 .env
파일을 생성하세요.
ATLAS_CONNECTION_STRING = "<connection-string>"
<connection-string>
자리 표시자 값을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다. 연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
참고
최소 Node.js 버전 요구 사항
Node.js v20.x --env-file
옵션을 도입했습니다. 이전 버전의 Node.js를 사용하는 경우 프로젝트에 dotenv
패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.
벡터 임베딩을 생성하는 함수를 정의합니다.
get-embeddings.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 주어진 입력에 대한 임베딩을 생성하는 함수를 정의합니다. 이 기능은 다음을 지정합니다.
Hugging Face의 transformers.js 라이브러리에서
feature-extraction
작업입니다. 자세한 내용은 작업을 참조하세요.nomic-embed-text-v1 임베딩 모델.
import { pipeline } from '@xenova/transformers'; // Function to generate embeddings for a given data source export async function getEmbedding(data) { const embedder = await pipeline( 'feature-extraction', 'Xenova/nomic-embed-text-v1'); const results = await embedder(data, { pooling: 'mean', normalize: true }); return Array.from(results.data); }
package.json
파일을 업데이트합니다.
ES 모듈을 사용하도록 프로젝트를 설정하려면 package.json
파일에 "type": "module"
을 추가한 후 저장합니다.
{ "type": "module", // other fields... }
.env
파일을 만듭니다.
프로젝트에서 .env
파일을 생성하여 Atlas 연결 문자열과 OpenAI API 키를 저장합니다.
OPENAI_API_KEY = "<api-key>" ATLAS_CONNECTION_STRING = "<connection-string>"
<api-key>
및 <connection-string>
자리 표시자 값을 OpenAI API 키와 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다. 연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
참고
최소 Node.js 버전 요구 사항
Node.js v20.x --env-file
옵션을 도입했습니다. 이전 버전의 Node.js를 사용하는 경우 프로젝트에 dotenv
패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.
벡터 임베딩을 생성하는 함수를 정의합니다.
get-embeddings.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 OpenAI의 text-embedding-3-small
모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는 getEmbedding
함수를 정의합니다.
import OpenAI from 'openai'; // Setup OpenAI configuration const openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY}); // Function to get the embeddings using the OpenAI API export async function getEmbedding(text) { const results = await openai.embeddings.create({ model: "text-embedding-3-small", input: text, encoding_format: "float", }); return results.data[0].embedding; }
이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. Nomic의 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI의 독점 모델을 사용할지 여부에 따라 탭 선택하세요.
오픈 소스 예시 binData
효율적인 처리 위해 임베딩을 BSON 벡터로 변환하는 함수도 포함되어 있습니다. 특정 임베딩 모델만 바이트 벡터 출력을 지원 . OpenAI의 모델과 같이 임베딩하지 않는 모델의 경우, Atlas Vector Search 인덱스 생성할 때 자동 양자화를 활성화 .
참고
오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.
벡터 임베딩을 생성하는 함수를 정의합니다.
Nomic AI의 오픈 소스 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 생성하려면 다음 코드를 노트북에 붙여넣고 실행하세요. . 이 코드는 다음을 수행합니다.
nomic-embed-text-v1 임베딩 모델을 로드합니다.
모델을 사용하여 지정된 텍스트 입력에 대해 기본값 정밀도,
int8
또는int1
임베딩으로 설정하다 되는float32
를 생성하는get_embedding
라는 함수를 만듭니다.
from sentence_transformers import SentenceTransformer from sentence_transformers.quantization import quantize_embeddings # Load the embedding model model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True) # Define a function to generate embeddings in multiple precisions def get_embedding(data, precision="float32"): return model.encode(data, precision=precision)
벡터 임베딩을 변환하는 함수를 정의합니다.
노트북에 다음 코드를 붙여넣고 실행 PyMongo 드라이버 사용하여 벡터 임베딩을 변환하는 함수를 만듭니다. 이라는 함수는 generate_bson_vector
float32
int8
int1
vector
벡터 데이터를 효율적으로 처리 위해 완전 충실도 임베딩을 BSON, 및 하위 유형으로 변환합니다.
from bson.binary import Binary # Generate BSON vector using `BinaryVectorDtype` def generate_bson_vector(vector, vector_dtype): return Binary.from_vector(vector, vector_dtype)
임베딩이 있는 문서를 생성하는 함수를 정의합니다.
노트북에 다음 코드를 붙여넣고 실행 임베딩이 있는 문서를 생성하는 create_docs_with_bson_vector_embeddings
이라는 함수를 만듭니다.
from bson.binary import Binary # Function to create documents with BSON vector embeddings def create_docs_with_bson_vector_embeddings(bson_float32, bson_int8, bson_int1, data): docs = [] for i, (bson_f32_emb, bson_int8_emb, bson_int1_emb, text) in enumerate(zip(bson_float32, bson_int8, bson_int1, data)): doc = { "_id": i, "data": text, "BSON-Float32-Embedding": bson_f32_emb, "BSON-Int8-Embedding": bson_int8_emb, "BSON-Int1-Embedding": bson_int1_emb, } docs.append(doc) return docs
함수를 테스트하여 임베딩을 생성합니다.
노트북에 다음 코드를 붙여넣고 실행 함수를 테스트하여 Nomic AI 사용하여 임베딩을 생성합니다.
이 코드는 문자열 foo
및 bar
에 대해 float32
, int8
, int1
임베딩을 생성합니다.
# Example generating embeddings for the strings "foo" and "bar" data = ["foo", "bar"] float32_embeddings = get_embedding(data, "float32") int8_embeddings = get_embedding(data, "int8") int1_embeddings = get_embedding(data, "ubinary") print("Float32 Embedding:", float32_embeddings) print("Int8 Embedding:", int8_embeddings) print("Int1 Embedding (binary representation):", int1_embeddings)
Float32 Embedding: [ [-0.02980827 0.03841474 -0.02561123 ... -0.0532876 -0.0335409 -0.02591543] [-0.02748881 0.03717749 -0.03104552 ... 0.02413219 -0.02402252 0.02810651] ] Int8 Embedding: [ [-128 127 127 ... -128 -128 -128] [ 126 -128 -128 ... 127 126 127] ] Int1 Embedding (binary representation): [ [ 77 30 4 131 15 123 146 ... 159 142 205 23 119 120] [ 79 82 208 180 45 79 209 ... 158 100 141 189 166 173] ]
함수를 테스트하여 임베딩을 BSON 벡터로 변환합니다.
노트북에 다음 코드를 붙여넣고 실행 PyMongo 운전자 사용하여 임베딩을 BSON 벡터로 변환하는 함수를 테스트합니다.
이 코드는 문자열 foo
및 bar
에 대한 float32
, int8
및 int1
임베딩을 양자화합니다.
from bson.binary import Binary, BinaryVectorDtype bson_float32_embeddings = [] bson_int8_embeddings = [] bson_int1_embeddings = [] for (f32_emb, int8_emb, int1_emb) in zip(float32_embeddings, int8_embeddings, int1_embeddings): bson_float32_embeddings.append(generate_bson_vector(f32_emb, BinaryVectorDtype.FLOAT32)) bson_int8_embeddings.append(generate_bson_vector(int8_emb, BinaryVectorDtype.INT8)) bson_int1_embeddings.append(generate_bson_vector(int1_emb, BinaryVectorDtype.PACKED_BIT)) # Print the embeddings print(f"The converted bson_float32_new_embedding is: {bson_float32_embeddings}") print(f"The converted bson_int8_new_embedding is: {bson_int8_embeddings}") print(f"The converted bson_int1_new_embedding is: {bson_int1_embeddings}")
The converted bson_float32_new_embedding is: [Binary(b'\'\x00x0\xf4\ ... x9bL\xd4\xbc', 9), Binary(b'\'\x007 ... \x9e?\xe6<', 9)] The converted bson_int8_new_embedding is: [Binary(b'\x03\x00\x80\x7f\ ... x80\x80', 9), Binary(b'\x03\x00~\x80 ... \x7f', 9)] The converted bson_int1_new_embedding is: [Binary(b'\x10\x00M\x1e\ ... 7wx', 9), Binary(b'\x10\x00OR\ ... \xa6\xad', 9)]
벡터 임베딩을 생성하는 함수를 정의합니다.
OpenAI의 독점 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 생성하려면 다음 코드를 노트북에 붙여넣고 실행하세요. <api-key>
를 OpenAI API 키로 바꾸세요. 이 코드는 다음을 수행합니다.
text-embedding-3-small
임베딩 모델을 지정합니다.주어진 텍스트 입력에 대한 임베딩을 생성하기 위해 모델의 API를 호출하는
get_embedding
이라는 함수를 생성합니다.문자열
foo
에 대한 단일 임베딩을 생성하여 함수를 테스트합니다.
import os from openai import OpenAI # Specify your OpenAI API key and embedding model os.environ["OPENAI_API_KEY"] = "<api-key>" model = "text-embedding-3-small" openai_client = OpenAI() # Define a function to generate embeddings def get_embedding(text): """Generates vector embeddings for the given text.""" embedding = openai_client.embeddings.create(input = [text], model=model).data[0].embedding return embedding # Generate an embedding get_embedding("foo")
[-0.005843308754265308, -0.013111298903822899, -0.014585349708795547, 0.03580040484666824, 0.02671629749238491, ... ]
데이터에서 임베딩 생성
이 섹션에서는 정의한 함수를 사용하여 데이터에서 벡터 임베딩을 만든 다음 이러한 임베딩을 Atlas 의 컬렉션 에 저장 합니다.
새 데이터에서 임베딩을 만들 것인지, 아니면 Atlas에 이미 있는 기존 데이터에서 임베딩을 만들 것인지에 따라 탭을 선택합니다.
DataService
클래스를 정의합니다.
이름이 같은 이름의 파일 에 새 클래스를 DataService.cs
만들고 다음 코드를 붙여넣습니다. 이 코드는 이라는 이름의 비동기 AddDocumentsAsync
작업을 정의하여 Atlas 에 문서를 추가합니다. 이 함수는 Collection.InsertManyAsync() C# 드라이버 메서드를 사용하여 유형의 목록을 BsonDocument
삽입합니다. 각 문서 에는 다음이 포함됩니다.
영화 요약이 포함된
text
필드 입니다.벡터 임베딩을 생성할 때 발생하는 부동 소수점 배열 이 포함된
embedding
필드 입니다.
namespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_db"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("embeddings"); public async Task AddDocumentsAsync(Dictionary<string, float[]> embeddings) { var documents = new List<BsonDocument>(); foreach( KeyValuePair<string, float[]> var in embeddings ) { var document = new BsonDocument { { "text", var.Key }, { "embedding", new BsonArray(var.Value) } }; documents.Add(document); } await Collection.InsertManyAsync(documents); Console.WriteLine($"Successfully inserted {embeddings.Count} documents into Atlas"); documents.Clear(); } }
Program.cs
프로젝트 에서 을(를) 업데이트합니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.
구체적으로, 이 코드는 정의한 GetEmbeddingsAsync
함수를 사용하여 샘플 텍스트 배열 에서 임베딩을 생성하고 Atlas 의 sample_db.embeddings
컬렉션 으로 수집합니다.
using MyCompany.Embeddings; var aiService = new AIService(); var texts = new string[] { "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission" }; var embeddings = await aiService.GetEmbeddingsAsync(texts); var dataService = new DataService(); await dataService.AddDocumentsAsync(embeddings);
프로젝트 를 컴파일하고 실행 합니다.
dotnet run MyCompany.Embeddings.csproj
Successfully inserted 3 documents into Atlas
클러스터의 sample_db.embeddings
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
DataService
클래스를 정의합니다.
이름이 같은 이름의 파일 DataService.cs
에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 다음을 수행하는 두 개의 함수를 생성합니다.
Atlas cluster에 연결합니다.
GetDocuments
메서드는 비어 있지 않은summary
필드 있는sample_airbnb.listingsAndReviews
컬렉션 에서 문서의 하위 집합을 가져옵니다.AddEmbeddings
비동기 작업은_id
가GetDocuments
메서드에서 검색된 문서 중 하나와 일치하는sample_airbnb.listingsAndReviews
컬렉션 의 문서에 새embeddings
필드 만듭니다.
namespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_airbnb"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("listingsAndReviews"); public List<BsonDocument>? GetDocuments() { var filter = Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Exists("summary", true), Builders<BsonDocument>.Filter.Ne("summary", "") ), Builders<BsonDocument>.Filter.Exists("embeddings", false) ); return Collection.Find(filter).Limit(50).ToList(); } public async Task<long> AddEmbeddings(Dictionary<string, float[]> embeddings) { var listWrites = new List<WriteModel<BsonDocument>>(); foreach( var kvp in embeddings ) { var filterForUpdate = Builders<BsonDocument>.Filter.Eq("summary", kvp.Key); var updateDefinition = Builders<BsonDocument>.Update.Set("embeddings", kvp.Value); listWrites.Add(new UpdateOneModel<BsonDocument>(filterForUpdate, updateDefinition)); } var result = await Collection.BulkWriteAsync(listWrites); listWrites.Clear(); return result.ModifiedCount; } }
Program.cs
프로젝트 에서 을(를) 업데이트합니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.
구체적으로, 이 코드는 정의한 GetEmbeddingsAsync
함수를 사용하여 샘플 텍스트 배열 에서 임베딩을 생성하고 Atlas 의 sample_db.embeddings
컬렉션 으로 수집합니다.
using MyCompany.Embeddings; var dataService = new DataService(); var documents = dataService.GetDocuments(); if (documents != null) { Console.WriteLine("Generating embeddings."); var aiService = new AIService(); var summaries = new List<string>(); foreach (var document in documents) { var summary = document.GetValue("summary").ToString(); if (summary != null) { summaries.Add(summary); } } try { if (summaries.Count > 0) { var embeddings = await aiService.GetEmbeddingsAsync(summaries.ToArray()); try { var updatedCount = await dataService.AddEmbeddings(embeddings); Console.WriteLine($"{updatedCount} documents updated successfully."); } catch (Exception e) { Console.WriteLine($"Error adding embeddings to MongoDB: {e.Message}"); } } } catch (Exception e) { Console.WriteLine($"Error creating embeddings for summaries: {e.Message}"); } } else { Console.WriteLine("No documents found"); }
create-embeddings.go
라는 이름의 파일을 생성하고 다음 코드를 붙여넣습니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.
구체적으로, 이 코드는 사용자가 정의한 GetEmbeddings
함수와 MongoDB Go 드라이버를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 Atlas에서 sample_db.embeddings
컬렉션으로 수집합니다.
package main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var data = []string{ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", } type TextWithEmbedding struct { Text string Embedding []float32 } func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") embeddings := common.GetEmbeddings(data) docsToInsert := make([]interface{}, len(embeddings)) for i, string := range data { docsToInsert[i] = TextWithEmbedding{ Text: string, Embedding: embeddings[i], } } result, err := coll.InsertMany(ctx, docsToInsert) if err != nil { log.Fatalf("failed to insert documents: %v", err) } fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs)) }
package main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var data = []string{ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", } type TextWithEmbedding struct { Text string Embedding []float64 } func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") embeddings := common.GetEmbeddings(data) docsToInsert := make([]interface{}, len(data)) for i, movie := range data { docsToInsert[i] = TextWithEmbedding{ Text: movie, Embedding: embeddings[i], } } result, err := coll.InsertMany(ctx, docsToInsert) if err != nil { log.Fatalf("failed to insert documents: %v", err) } fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs)) }
파일을 저장하고 실행합니다.
go run create-embeddings.go
Successfully inserted 3 documents into Atlas
go run create-embeddings.go
Successfully inserted 3 documents into Atlas
클러스터의 sample_db.embeddings
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
create-embeddings.go
라는 이름의 파일을 생성하고 다음 코드를 붙여넣습니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다. 구체적으로 이 코드는 다음을 수행합니다.
Atlas 클러스터에 연결합니다.
sample_airbnb.listingsAndReviews
컬렉션에서summary
필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.정의한
GetEmbeddings
함수를 사용하여 각 문서의summary
필드에서 임베딩을 생성합니다.MongoDB Go 드라이버를 사용하여 임베딩 값이 포함된 새
embeddings
필드로 각 문서를 업데이트합니다.
package main import ( "context" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") filter := bson.D{ {"$and", bson.A{ bson.D{ {"$and", bson.A{ bson.D{{"summary", bson.D{{"$exists", true}}}}, bson.D{{"summary", bson.D{{"$ne", ""}}}}, }, }}, bson.D{{"embeddings", bson.D{{"$exists", false}}}}, }}, } opts := options.Find().SetLimit(50) cursor, err := coll.Find(ctx, filter, opts) if err != nil { log.Fatalf("failed to retrieve documents: %v", err) } var listings []common.Listing if err = cursor.All(ctx, &listings); err != nil { log.Fatalf("failed to unmarshal retrieved documents to Listing object: %v", err) } var summaries []string for _, listing := range listings { summaries = append(summaries, listing.Summary) } log.Println("Generating embeddings.") embeddings := common.GetEmbeddings(summaries) docsToUpdate := make([]mongo.WriteModel, len(listings)) for i := range listings { docsToUpdate[i] = mongo.NewUpdateOneModel(). SetFilter(bson.D{{"_id", listings[i].ID}}). SetUpdate(bson.D{{"$set", bson.D{{"embeddings", embeddings[i]}}}}) } bulkWriteOptions := options.BulkWrite().SetOrdered(false) result, err := coll.BulkWrite(context.Background(), docsToUpdate, bulkWriteOptions) if err != nil { log.Fatalf("failed to write embeddings to existing documents: %v", err) } log.Printf("Successfully added embeddings to %v documents", result.ModifiedCount) }
컬렉션 에 대한 고 (Go) 모델이 포함된 파일 을 만듭니다.
BSON 과의 고 (Go) 객체 마셜링 및 언마셜링을 간소화하려면 이 컬렉션 의 문서에 대한 모델이 포함된 파일 을 만듭니다.
common
디렉토리 로 이동합니다.cd common models.go
이라는 파일 을 만들고 다음 코드를 붙여넣습니다.models.gopackage common import ( "time" "go.mongodb.org/mongo-driver/bson/primitive" ) type Image struct { ThumbnailURL string `bson:"thumbnail_url"` MediumURL string `bson:"medium_url"` PictureURL string `bson:"picture_url"` XLPictureURL string `bson:"xl_picture_url"` } type Host struct { ID string `bson:"host_id"` URL string `bson:"host_url"` Name string `bson:"host_name"` Location string `bson:"host_location"` About string `bson:"host_about"` ThumbnailURL string `bson:"host_thumbnail_url"` PictureURL string `bson:"host_picture_url"` Neighborhood string `bson:"host_neighborhood"` IsSuperhost bool `bson:"host_is_superhost"` HasProfilePic bool `bson:"host_has_profile_pic"` IdentityVerified bool `bson:"host_identity_verified"` ListingsCount int32 `bson:"host_listings_count"` TotalListingsCount int32 `bson:"host_total_listings_count"` Verifications []string `bson:"host_verifications"` } type Location struct { Type string `bson:"type"` Coordinates []float64 `bson:"coordinates"` IsLocationExact bool `bson:"is_location_exact"` } type Address struct { Street string `bson:"street"` Suburb string `bson:"suburb"` GovernmentArea string `bson:"government_area"` Market string `bson:"market"` Country string `bson:"Country"` CountryCode string `bson:"country_code"` Location Location `bson:"location"` } type Availability struct { Thirty int32 `bson:"availability_30"` Sixty int32 `bson:"availability_60"` Ninety int32 `bson:"availability_90"` ThreeSixtyFive int32 `bson:"availability_365"` } type ReviewScores struct { Accuracy int32 `bson:"review_scores_accuracy"` Cleanliness int32 `bson:"review_scores_cleanliness"` CheckIn int32 `bson:"review_scores_checkin"` Communication int32 `bson:"review_scores_communication"` Location int32 `bson:"review_scores_location"` Value int32 `bson:"review_scores_value"` Rating int32 `bson:"review_scores_rating"` } type Review struct { ID string `bson:"_id"` Date time.Time `bson:"date,omitempty"` ListingId string `bson:"listing_id"` ReviewerId string `bson:"reviewer_id"` ReviewerName string `bson:"reviewer_name"` Comments string `bson:"comments"` } type Listing struct { ID string `bson:"_id"` ListingURL string `bson:"listing_url"` Name string `bson:"name"` Summary string `bson:"summary"` Space string `bson:"space"` Description string `bson:"description"` NeighborhoodOverview string `bson:"neighborhood_overview"` Notes string `bson:"notes"` Transit string `bson:"transit"` Access string `bson:"access"` Interaction string `bson:"interaction"` HouseRules string `bson:"house_rules"` PropertyType string `bson:"property_type"` RoomType string `bson:"room_type"` BedType string `bson:"bed_type"` MinimumNights string `bson:"minimum_nights"` MaximumNights string `bson:"maximum_nights"` CancellationPolicy string `bson:"cancellation_policy"` LastScraped time.Time `bson:"last_scraped,omitempty"` CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"` FirstReview time.Time `bson:"first_review,omitempty"` LastReview time.Time `bson:"last_review,omitempty"` Accommodates int32 `bson:"accommodates"` Bedrooms int32 `bson:"bedrooms"` Beds int32 `bson:"beds"` NumberOfReviews int32 `bson:"number_of_reviews"` Bathrooms primitive.Decimal128 `bson:"bathrooms"` Amenities []string `bson:"amenities"` Price primitive.Decimal128 `bson:"price"` WeeklyPrice primitive.Decimal128 `bson:"weekly_price"` MonthlyPrice primitive.Decimal128 `bson:"monthly_price"` CleaningFee primitive.Decimal128 `bson:"cleaning_fee"` ExtraPeople primitive.Decimal128 `bson:"extra_people"` GuestsIncluded primitive.Decimal128 `bson:"guests_included"` Image Image `bson:"images"` Host Host `bson:"host"` Address Address `bson:"address"` Availability Availability `bson:"availability"` ReviewScores ReviewScores `bson:"review_scores"` Reviews []Review `bson:"reviews"` Embeddings []float32 `bson:"embeddings,omitempty"` } models.gopackage common import ( "time" "go.mongodb.org/mongo-driver/bson/primitive" ) type Image struct { ThumbnailURL string `bson:"thumbnail_url"` MediumURL string `bson:"medium_url"` PictureURL string `bson:"picture_url"` XLPictureURL string `bson:"xl_picture_url"` } type Host struct { ID string `bson:"host_id"` URL string `bson:"host_url"` Name string `bson:"host_name"` Location string `bson:"host_location"` About string `bson:"host_about"` ThumbnailURL string `bson:"host_thumbnail_url"` PictureURL string `bson:"host_picture_url"` Neighborhood string `bson:"host_neighborhood"` IsSuperhost bool `bson:"host_is_superhost"` HasProfilePic bool `bson:"host_has_profile_pic"` IdentityVerified bool `bson:"host_identity_verified"` ListingsCount int32 `bson:"host_listings_count"` TotalListingsCount int32 `bson:"host_total_listings_count"` Verifications []string `bson:"host_verifications"` } type Location struct { Type string `bson:"type"` Coordinates []float64 `bson:"coordinates"` IsLocationExact bool `bson:"is_location_exact"` } type Address struct { Street string `bson:"street"` Suburb string `bson:"suburb"` GovernmentArea string `bson:"government_area"` Market string `bson:"market"` Country string `bson:"Country"` CountryCode string `bson:"country_code"` Location Location `bson:"location"` } type Availability struct { Thirty int32 `bson:"availability_30"` Sixty int32 `bson:"availability_60"` Ninety int32 `bson:"availability_90"` ThreeSixtyFive int32 `bson:"availability_365"` } type ReviewScores struct { Accuracy int32 `bson:"review_scores_accuracy"` Cleanliness int32 `bson:"review_scores_cleanliness"` CheckIn int32 `bson:"review_scores_checkin"` Communication int32 `bson:"review_scores_communication"` Location int32 `bson:"review_scores_location"` Value int32 `bson:"review_scores_value"` Rating int32 `bson:"review_scores_rating"` } type Review struct { ID string `bson:"_id"` Date time.Time `bson:"date,omitempty"` ListingId string `bson:"listing_id"` ReviewerId string `bson:"reviewer_id"` ReviewerName string `bson:"reviewer_name"` Comments string `bson:"comments"` } type Listing struct { ID string `bson:"_id"` ListingURL string `bson:"listing_url"` Name string `bson:"name"` Summary string `bson:"summary"` Space string `bson:"space"` Description string `bson:"description"` NeighborhoodOverview string `bson:"neighborhood_overview"` Notes string `bson:"notes"` Transit string `bson:"transit"` Access string `bson:"access"` Interaction string `bson:"interaction"` HouseRules string `bson:"house_rules"` PropertyType string `bson:"property_type"` RoomType string `bson:"room_type"` BedType string `bson:"bed_type"` MinimumNights string `bson:"minimum_nights"` MaximumNights string `bson:"maximum_nights"` CancellationPolicy string `bson:"cancellation_policy"` LastScraped time.Time `bson:"last_scraped,omitempty"` CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"` FirstReview time.Time `bson:"first_review,omitempty"` LastReview time.Time `bson:"last_review,omitempty"` Accommodates int32 `bson:"accommodates"` Bedrooms int32 `bson:"bedrooms"` Beds int32 `bson:"beds"` NumberOfReviews int32 `bson:"number_of_reviews"` Bathrooms primitive.Decimal128 `bson:"bathrooms"` Amenities []string `bson:"amenities"` Price primitive.Decimal128 `bson:"price"` WeeklyPrice primitive.Decimal128 `bson:"weekly_price"` MonthlyPrice primitive.Decimal128 `bson:"monthly_price"` CleaningFee primitive.Decimal128 `bson:"cleaning_fee"` ExtraPeople primitive.Decimal128 `bson:"extra_people"` GuestsIncluded primitive.Decimal128 `bson:"guests_included"` Image Image `bson:"images"` Host Host `bson:"host"` Address Address `bson:"address"` Availability Availability `bson:"availability"` ReviewScores ReviewScores `bson:"review_scores"` Reviews []Review `bson:"reviews"` Embeddings []float64 `bson:"embeddings,omitempty"` } 프로젝트 루트 디렉토리 로 다시 이동합니다.
cd ../
임베딩을 생성합니다.
go run create-embeddings.go
2024/10/10 09:58:03 Generating embeddings. 2024/10/10 09:58:12 Successfully added embeddings to 50 documents
Atlas UI에서 sample_airbnb.listingsAndReviews
컬렉션으로 이동하여 생성된 벡터 임베딩을 확인할 수 있습니다.
Atlas 의 기존 컬렉션 에서 임베딩을 생성하는 코드를 정의합니다.
CreateEmbeddings.java
이라는 파일을 만들고 다음 코드를 붙여넣습니다.
이 코드는 getEmbeddings
메서드와 MongoDB Java 동기화 드라이버 를 사용하여 다음을 수행합니다.
Atlas cluster에 연결합니다.
샘플 텍스트의 배열 을 가져옵니다.
이전에 정의한
getEmbeddings
메서드를 사용하여 각 텍스트에서 임베딩을 생성합니다.Atlas 의
sample_db.embeddings
컬렉션 에 임베딩을 수집합니다.
import com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.result.InsertManyResult; import org.bson.BsonArray; import org.bson.Document; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class CreateEmbeddings { static List<String> data = Arrays.asList( "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission" ); public static void main(String[] args){ String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new RuntimeException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_db"); MongoCollection<Document> collection = database.getCollection("embeddings"); System.out.println("Creating embeddings for " + data.size() + " documents"); EmbeddingProvider embeddingProvider = new EmbeddingProvider(); // generate embeddings for new inputted data List<BsonArray> embeddings = embeddingProvider.getEmbeddings(data); List<Document> documents = new ArrayList<>(); int i = 0; for (String text : data) { Document doc = new Document("text", text).append("embedding", embeddings.get(i)); documents.add(doc); i++; } // insert the embeddings into the Atlas collection List<String> insertedIds = new ArrayList<>(); try { InsertManyResult result = collection.insertMany(documents); result.getInsertedIds().values() .forEach(doc -> insertedIds.add(doc.toString())); System.out.println("Inserted " + insertedIds.size() + " documents with the following ids to " + collection.getNamespace() + " collection: \n " + insertedIds); } catch (MongoException me) { throw new RuntimeException("Failed to insert documents", me); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } }
임베딩을 생성합니다.
파일을 저장하고 실행합니다. 출력은 다음과 같습니다.
Creating embeddings for 3 documents Inserted 3 documents with the following ids to sample_db.embeddings collection: [BsonObjectId{value=6735ff620d88451041f6dd40}, BsonObjectId{value=6735ff620d88451041f6dd41}, BsonObjectId{value=6735ff620d88451041f6dd42}]
클러스터의 sample_db.embeddings
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
Atlas 의 기존 컬렉션 에서 임베딩을 생성하는 코드를 정의합니다.
CreateEmbeddings.java
이라는 파일을 만들고 다음 코드를 붙여넣습니다.
이 코드는 getEmbeddings
메서드와 MongoDB Java 동기화 드라이버 를 사용하여 다음을 수행합니다.
Atlas cluster에 연결합니다.
비어 있지 않은
summary
필드 가 있는sample_airbnb.listingsAndReviews
컬렉션 에서 문서의 하위 집합을 가져옵니다.이전에 정의한
getEmbeddings
메서드를 사용하여 각 문서의summary
필드 에서 임베딩을 생성합니다.임베딩 값이 포함된 새
embeddings
필드 로 각 문서 를 업데이트합니다.
import com.mongodb.MongoException; import com.mongodb.bulk.BulkWriteResult; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.BulkWriteOptions; import com.mongodb.client.model.Filters; import com.mongodb.client.model.UpdateOneModel; import com.mongodb.client.model.Updates; import com.mongodb.client.model.WriteModel; import org.bson.BsonArray; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.List; public class CreateEmbeddings { public static void main(String[] args){ String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new RuntimeException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_airbnb"); MongoCollection<Document> collection = database.getCollection("listingsAndReviews"); Bson filterCriteria = Filters.and( Filters.and(Filters.exists("summary"), Filters.ne("summary", null), Filters.ne("summary", "")), Filters.exists("embeddings", false)); try (MongoCursor<Document> cursor = collection.find(filterCriteria).limit(50).iterator()) { List<String> summaries = new ArrayList<>(); List<String> documentIds = new ArrayList<>(); int i = 0; while (cursor.hasNext()) { Document document = cursor.next(); String summary = document.getString("summary"); String id = document.get("_id").toString(); summaries.add(summary); documentIds.add(id); i++; } System.out.println("Generating embeddings for " + summaries.size() + " documents."); System.out.println("This operation may take up to several minutes."); EmbeddingProvider embeddingProvider = new EmbeddingProvider(); List<BsonArray> embeddings = embeddingProvider.getEmbeddings(summaries); List<WriteModel<Document>> updateDocuments = new ArrayList<>(); for (int j = 0; j < summaries.size(); j++) { UpdateOneModel<Document> updateDoc = new UpdateOneModel<>( Filters.eq("_id", documentIds.get(j)), Updates.set("embeddings", embeddings.get(j))); updateDocuments.add(updateDoc); } int updatedDocsCount = 0; try { BulkWriteOptions options = new BulkWriteOptions().ordered(false); BulkWriteResult result = collection.bulkWrite(updateDocuments, options); updatedDocsCount = result.getModifiedCount(); } catch (MongoException me) { throw new RuntimeException("Failed to insert documents", me); } System.out.println("Added embeddings successfully to " + updatedDocsCount + " documents."); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } }
임베딩을 생성합니다.
파일을 저장하고 실행합니다. 출력은 다음과 같습니다.
Generating embeddings for 50 documents. This operation may take up to several minutes. Added embeddings successfully to 50 documents.
클러스터의 sample_airbnb.listingsAndReviews
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.
create-embeddings.js
라는 이름의 파일을 생성하고 다음 코드를 붙여넣습니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.
구체적으로, 이 코드는 사용자가 정의한 getEmbedding
함수와 MongoDB Node.js 드라이버를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 Atlas의 sample_db.embeddings
컬렉션으로 수집합니다.
import { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // Data to embed const data = [ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission" ] async function run() { // Connect to your Atlas cluster const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); try { await client.connect(); const db = client.db("sample_db"); const collection = db.collection("embeddings"); await Promise.all(data.map(async text => { // Check if the document already exists const existingDoc = await collection.findOne({ text: text }); // Generate an embedding by using the function that you defined const embedding = await getEmbedding(text); // Ingest data and embedding into Atlas if (!existingDoc) { await collection.insertOne({ text: text, embedding: embedding }); console.log(embedding); } })); } catch (err) { console.log(err.stack); } finally { await client.close(); } } run().catch(console.dir);
파일을 저장하고 실행합니다.
node --env-file=.env create-embeddings.js
[ -0.04323853924870491, -0.008460805751383305, 0.012494648806750774, -0.013014335185289383, ... ] [ -0.017400473356246948, 0.04922063276171684, -0.002836339408531785, -0.030395228415727615, ... ] [ -0.016950927674770355, 0.013881809078156948, -0.022074559703469276, -0.02838018536567688, ... ]
node --env-file=.env create-embeddings.js
[ 0.031927742, -0.014192767, -0.021851597, 0.045498233, -0.0077904654, ... ] [ -0.01664538, 0.013198251, 0.048684783, 0.014485021, -0.018121032, ... ] [ 0.030449908, 0.046782598, 0.02126599, 0.025799986, -0.015830345, ... ]
참고
출력의 차원 수는 가독성을 위해 일부만 표시되었습니다.
클러스터의 sample_db.embeddings
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
create-embeddings.js
라는 이름의 파일을 생성하고 다음 코드를 붙여넣습니다.
다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다. 구체적으로 이 코드는 다음을 수행합니다.
Atlas 클러스터에 연결합니다.
sample_airbnb.listingsAndReviews
컬렉션에서summary
필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.정의한
getEmbedding
함수를 사용하여 각 문서의summary
필드에서 임베딩을 생성합니다.MongoDB Node.js 드라이버를 사용하여 임베딩 값이 포함된 새
embedding
필드로 각 문서를 업데이트합니다.
import { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // Connect to your Atlas cluster const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { await client.connect(); const db = client.db("sample_airbnb"); const collection = db.collection("listingsAndReviews"); // Filter to exclude null or empty summary fields const filter = { "summary": { "$nin": [ null, "" ] } }; // Get a subset of documents from the collection const documents = await collection.find(filter).limit(50).toArray(); // Create embeddings from a field in the collection let updatedDocCount = 0; console.log("Generating embeddings for documents..."); await Promise.all(documents.map(async doc => { // Generate an embedding by using the function that you defined const embedding = await getEmbedding(doc.summary); // Update the document with a new embedding field await collection.updateOne({ "_id": doc._id }, { "$set": { "embedding": embedding } } ); updatedDocCount += 1; })); console.log("Count of documents updated: " + updatedDocCount); } catch (err) { console.log(err.stack); } finally { await client.close(); } } run().catch(console.dir);
파일을 저장하고 실행합니다.
node --env-file=.env create-embeddings.js
Generating embeddings for documents... Count of documents updated: 50
Atlas UI 에서 컬렉션 으로 이동하고 문서 의 필드를 확장하면 생성되는 벡터 임베딩을 볼 수 있습니다.sample_airbnb.listingsAndReviews
(조건부) BSON 임베딩을 생성하는함수를 정의합니다.
get_embedding
generate_bson_vector
노트북에, 및 create_docs_with_bson_vector_embeddings
함수를 아직 로드하지 않은 경우, 노트북에 이러한 함수를 로드하려면 임베딩 함수 정의를 참조하세요.
샘플 데이터를 불러옵니다.
다음 코드를 노트북에 붙여넣고 실행합니다.
# Sample data sentences = [ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", "Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious.", "The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son.", "Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life.", "Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.", "The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers.", "Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire.", "The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.", "Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past.", "The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy.", "Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love.", "The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer.", "E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home.", "Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action.", "Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family.", "Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion.", "Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude.", "Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory." ]
데이터에 대한 임베딩을 생성합니다.
다음 코드를 사용하여 새로운 데이터에서 임베딩을 생성합니다.
구체적으로, 이 코드는 사용자가 정의한 get_embedding
함수와 PyMongo 드라이버 사용하여 샘플 텍스트 배열 에서 임베딩을 생성합니다.
import pymongo from sentence_transformers.quantization import quantize_embeddings float32_embeddings = get_embedding(sentences, precision="float32") int8_embeddings = get_embedding(sentences, precision="int8") int1_embeddings = get_embedding(sentences, precision="ubinary") # Print stored embeddings print("Generated embeddings stored in different variables:") for i, text in enumerate(sentences): print(f"\nText: {text}") print(f"Float32 Embedding: {float32_embeddings[i][:3]}... (truncated)") print(f"Int8 Embedding: {int8_embeddings[i][:3]}... (truncated)") print(f"Ubinary Embedding: {int1_embeddings[i][:3]}... (truncated)")
Generated embeddings stored in different variables: Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Float32 Embedding: [-0.01089042 0.05926645 -0.00291325]... (truncated) Int8 Embedding: [-15 127 56]... (truncated) Ubinary Embedding: [ 77 30 209]... (truncated) Text: The Lion King: Lion cub and future king Simba searches for his identity Float32 Embedding: [-0.05607051 -0.01360618 0.00523855]... (truncated) Int8 Embedding: [-128 -109 110]... (truncated) Ubinary Embedding: [ 37 18 151]... (truncated) Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Float32 Embedding: [-0.0275258 0.01144342 -0.02360895]... (truncated) Int8 Embedding: [-57 -28 -79]... (truncated) Ubinary Embedding: [ 76 16 144]... (truncated) Text: Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious. Float32 Embedding: [-0.01759741 0.03254957 -0.02090798]... (truncated) Int8 Embedding: [-32 40 -61]... (truncated) Ubinary Embedding: [ 77 27 176]... (truncated) Text: The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son. Float32 Embedding: [ 0.00503172 0.04311579 -0.00074904]... (truncated) Int8 Embedding: [23 74 70]... (truncated) Ubinary Embedding: [215 26 145]... (truncated) Text: Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life. Float32 Embedding: [0.02349479 0.05669326 0.00458773]... (truncated) Int8 Embedding: [ 69 118 105]... (truncated) Ubinary Embedding: [237 154 159]... (truncated) Text: Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry. Float32 Embedding: [-0.03294644 0.02671233 -0.01864981]... (truncated) Int8 Embedding: [-70 21 -47]... (truncated) Ubinary Embedding: [ 77 90 146]... (truncated) Text: The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers. Float32 Embedding: [-0.02489671 0.02847196 -0.00290637]... (truncated) Int8 Embedding: [-50 27 56]... (truncated) Ubinary Embedding: [ 95 154 129]... (truncated) Text: Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire. Float32 Embedding: [-0.01235448 0.01524397 -0.01063425]... (truncated) Int8 Embedding: [-19 -15 5]... (truncated) Ubinary Embedding: [ 68 26 210]... (truncated) Text: The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover. Float32 Embedding: [ 0.04665203 0.01392298 -0.01743002]... (truncated) Int8 Embedding: [127 -20 -39]... (truncated) Ubinary Embedding: [207 88 208]... (truncated) Text: Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past. Float32 Embedding: [0.00929601 0.04206405 0.00701248]... (truncated) Int8 Embedding: [ 34 71 121]... (truncated) Ubinary Embedding: [228 90 130]... (truncated) Text: The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy. Float32 Embedding: [-0.01451324 -0.00897367 0.0077793 ]... (truncated) Int8 Embedding: [-24 -94 127]... (truncated) Ubinary Embedding: [ 57 150 32]... (truncated) Text: Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love. Float32 Embedding: [-0.01458643 0.03639758 -0.02587282]... (truncated) Int8 Embedding: [-25 52 -94]... (truncated) Ubinary Embedding: [ 78 218 216]... (truncated) Text: The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer. Float32 Embedding: [-0.00205381 -0.00039482 -0.01630799]... (truncated) Int8 Embedding: [ 6 -66 -31]... (truncated) Ubinary Embedding: [ 9 82 154]... (truncated) Text: E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home. Float32 Embedding: [ 0.01105334 0.00776658 -0.03092942]... (truncated) Int8 Embedding: [ 38 -40 -128]... (truncated) Ubinary Embedding: [205 24 146]... (truncated) Text: Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. Float32 Embedding: [ 0.00266668 -0.01926583 -0.00727963]... (truncated) Int8 Embedding: [ 17 -128 27]... (truncated) Ubinary Embedding: [148 82 194]... (truncated) Text: Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family. Float32 Embedding: [-0.00031873 -0.01352339 -0.02882693]... (truncated) Int8 Embedding: [ 10 -109 -114]... (truncated) Ubinary Embedding: [ 12 26 144]... (truncated) Text: Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion. Float32 Embedding: [ 0.00957429 0.01855557 -0.02353773]... (truncated) Int8 Embedding: [ 34 -5 -79]... (truncated) Ubinary Embedding: [212 18 144]... (truncated) Text: Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude. Float32 Embedding: [-0.01787405 0.03672816 -0.00972007]... (truncated) Int8 Embedding: [-33 53 11]... (truncated) Ubinary Embedding: [ 68 154 145]... (truncated) Text: Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory. Float32 Embedding: [-0.03515214 -0.00503571 0.00183181]... (truncated) Int8 Embedding: [-76 -81 87]... (truncated) Ubinary Embedding: [ 35 222 152]... (truncated)
임베딩에서 BSON 벡터를 생성합니다.
다음 코드를 사용하여 생성된 벡터 임베딩을 BSON 벡터로 변환합니다. 이 코드는 PyMongo 운전자 사용합니다.
구체적으로, 이 코드는 생성된 임베딩을 float32
, int8
및 비트팩 int1
유형으로 변환한 다음 float32
, int8
및 int1
벡터를 양자화합니다.
from bson.binary import Binary, BinaryVectorDtype bson_float32_embeddings = [] bson_int8_embeddings = [] bson_int1_embeddings = [] # Convert each embedding to BSON for (f32_emb, int8_emb, int1_emb) in zip(float32_embeddings, int8_embeddings, int1_embeddings): bson_float32_embeddings.append(generate_bson_vector(f32_emb, BinaryVectorDtype.FLOAT32)) bson_int8_embeddings.append(generate_bson_vector(int8_emb, BinaryVectorDtype.INT8)) bson_int1_embeddings.append(generate_bson_vector(int1_emb, BinaryVectorDtype.PACKED_BIT)) # Print the embeddings for idx, text in enumerate(sentences): print(f"\nText: {text}") print(f"Float32 BSON: {bson_float32_embeddings[idx]}") print(f"Int8 BSON: {bson_int8_embeddings[idx]}") print(f"Int1 BSON: {bson_int1_embeddings[idx]}")
Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Float32 BSON: b'\'\x00\xbam2\xbc`\xc1r=7\xec>\xbb\xe6\xf3\x...' Int8 BSON: b'\x03\x00\xf1\x7f8\xdf\xfeC\x1e>\xef\xd6\xf5\x9...' Int1 BSON: b'\x10\x00M\x1e\xd1\xd2\x05\xaeq\xdf\x9a\x1d\xbc...' Text: The Lion King: Lion cub and future king Simba searches for his identity Float32 BSON: b'\'\x001\xaae\xbdr\xec^\xbc"\xa8\xab;\x91\xd...' Int8 BSON: b'\x03\x00\x80\x93n\x06\x80\xca\xd3.\xa2\xe3\xd1...' Int1 BSON: b'\x10\x00%\x12\x97\xa6\x8f\xdf\x89\x9d2\xcb\x99...' Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Float32 BSON: b'\'\x00\xcc}\xe1\xbc-};<\x8eg\xc1\xbc\xcb\xd...' Int8 BSON: b'\x03\x00\xc7\xe4\xb1\xdf/\xe2\xd2\x90\xf7\x02|...' Int1 BSON: b'\x10\x00L\x10\x90\xb6\x0f\x8a\x91\xaf\x92|\xf9...' Text: Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious. Float32 BSON: b'\'\x00o(\x90\xbc\xb3R\x05=8G\xab\xbc\xfb\xc...' Int8 BSON: b'\x03\x00\xe0(\xc3\x10*\xda\xfe\x19\xbf&<\xd1\x...' Int1 BSON: b'\x10\x00M\x1b\xb0\x86\rn\x93\xaf:w\x9f}\x92\xd...' Text: The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son. Float32 BSON: b'\'\x00\x1d\xe1\xa4;0\x9a0=C[D\xba\xb5\xf2\x...' Int8 BSON: b'\x03\x00\x17JF2\xb9\xddZ8\xa1\x0c\xc6\x80\xd8$...' Int1 BSON: b'\x10\x00\xd7\x1a\x91\x87\x0e\xc9\x91\x8b\xba\x...' Text: Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life. Float32 BSON: b'\'\x00#x\xc0<27h=\xb5T\x96;:\xc4\x9c\xbd\x1...' Int8 BSON: b'\x03\x00Evi\x80\x13\xd6\x1cCW\x80\x01\x9e\xe58...' Int1 BSON: b'\x10\x00\xed\x9a\x9f\x97\x1f.\x12\xf9\xba];\x7...' Text: Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry. Float32 BSON: b'\'\x00\xd9\xf2\x06\xbd\xd2\xd3\xda<\x7f\xc7...' Int8 BSON: b'\x03\x00\xba\x15\xd1-\x0c\x03\xe6\xea\rQ\x1f\x...' Int1 BSON: b'\x10\x00MZ\x92\xb7#\xaa\x99=\x9a\x99\x9c|<\xf8...' Text: The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers. Float32 BSON: b'\'\x00/\xf4\xcb\xbc\t>\xe9<\xc9x>\xbb\xcc\x...' Int8 BSON: b'\x03\x00\xce\x1b815\xcf1\xc6s\xe5\n\xe4\x192G\...' Int1 BSON: b'\x10\x00_\x9a\x81\xa6\x0f\x0f\x93o2\xd8\xfe|\x...' Text: Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire. Float32 BSON: b'\'\x00sjJ\xbc\xd6\xc1y<I;.\xbc\xb1\x80\t\xb...' Int8 BSON: b'\x03\x00\xed\xf1\x05\xe2\xc7\xfa\xd4\xab5\xeb\...' Int1 BSON: b'\x10\x00D\x1a\xd2\x86\x0ey\x92\x8f\xaa\x89\x1c...' Text: The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover. Float32 BSON: b'\'\x004\x16?=9\x1dd<g\xc9\x8e\xbc\xdf\x81\x...' Int8 BSON: b'\x03\x00\x7f\xec\xd9\xdc)\xd6)\x05\x18\x7f\xa6...' Int1 BSON: b"\x10\x00\xcfX\xd0\xb7\x0e\xcf\xd9\r\xf0U\xb4]6..." Text: Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past. Float32 BSON: b'\'\x00HN\x18<ZK,=\xf9\xc8\xe5;\x9e\xed\xa0\...' Int8 BSON: b'\x03\x00"Gy\x01\xeb\xec\xfc\x80\xe4a\x7f\x88\x...' Int1 BSON: b'\x10\x00\xe4Z\x82\xb6\xad\xec\x10-\x9a\x99;?j\...' Text: The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy. Float32 BSON: b'\'\x00\xef\xc8m\xbcJ\x06\x13\xbcv\xe9\xfe;...' Int8 BSON: b'\x03\x00\xe8\xa2\x7fIE\xba\x9f\xfaT2\xf1\xc1\...' Int1 BSON: b'\x10\x009\x96 \xb7\x8e\xc9\x81\xaf\xaa\x9f\xa...' Text: Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love. Float32 BSON: b'\'\x00\xee\xfbn\xbc\xa0\x15\x15=<\xf3\xd3x...' Int8 BSON: b'\x03\x00\xe74\xa2\xe5\x15\x165\xb9dM8C\xd7E\x...' Int1 BSON: b'\x10\x00N\xda\xd8\xb6\x03N\x98\xbd\xdaY\x1b| ...' Text: The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer. Float32 BSON: b'\'\x002\x99\x06\xbb\x82\x00\xcf\xb9X\x98\x...' Int8 BSON: b'\x03\x00\x06\xbe\xe1.\x7f\x80\x04C\xd7e\x80\x...' Int1 BSON: b'\x10\x00\tR\x9a\xd6\x0c\xb1\x9a\xbc\x90\xf5\x...' Text: E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home. Float32 BSON: b'\'\x00\x14\x195<\xd4~\xfe;\xb3_\xfd\xbc \xe...' Int8 BSON: b'\x03\x00&\xd8\x80\x92\x01\x7f\xbfF\xd4\x10\xf0...' Int1 BSON: b'\x10\x00\xcd\x18\x92\x92\x8dJ\x92\xbd\x9a\xd3\...' Text: Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. Float32 BSON: b'\'\x00\x8a\xc3.;_\xd3\x9d\xbc\xf2\x89\xee\x...' Int8 BSON: b'\x03\x00\x11\x80\x1b5\xe9\x19\x80\x8f\xb1N\xda...' Int1 BSON: b"\x10\x00\x94R\xc2\xd2\x0f\xfa\x90\xbc\xd8\xd6\...' Text: Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family. Float32 BSON: b'\'\x00\xe6\x1a\xa7\xb94\x91]\xbcs&\xec\xbc\...' Int8 BSON: b'\x03\x00\n\x93\x8e,n\xce\xe8\x9b@\x00\xf9\x7f\...' Int1 BSON: b'\x10\x00\x0c\x1a\x90\x97\x0f\x19\x80/\xba\x98\...' Text: Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion. Float32 BSON: b'\'\x00\x7f\xdd\x1c<\xd9\x01\x98<1\xd2\xc0\xb...' Int8 BSON: b'\x03\x00"\xfb\xb1\x7f\xd3\xd6\x04\xbe\x80\xf9L\...' Int1 BSON: b'\x10\x00\xd4\x12\x90\xa6\x8by\x99\x8d\xa2\xbd\x...' Text: Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude. Float32 BSON: b'\'\x00\x98l\x92\xbcDp\x16=\xf0@\x1f\xbc\xd0\...' Int8 BSON: b'\x03\x00\xdf5\x0b\xe3\xbf\xe5\xa5\xad\x7f\x02\x...' Int1 BSON: b'\x10\x00D\x9a\x91\x96\x07\xfa\x93\x8d\xb2D\x92]...' Text: Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory. Float32 BSON: b'\'\x00\xb0\xfb\x0f\xbd\x9b\x02\xa5\xbbZ\x19\...' Int8 BSON: b'\x03\x00\xb4\xafW\xd9\xd7\xc3\x7f~QM\x86\x83\xf...' Int1 BSON: b'\x10\x00#\xde\x98\x96\x0e\xcc\x12\xf6\xbb\xdd2}...'
Atlas cluster 에 연결하여 데이터를 업로드합니다.
다음 코드를 노트북에 붙여넣고 <connection-string>
를 Atlas 클러스터의 SRV 연결 문자열 로 바꾼 다음 코드를 실행 .
참고
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_db"] collection = db["embeddings"] # Ingest data into Atlas collection.insert_many(docs)
InsertManyResult([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], acknowledged=True)
벡터 임베딩은 sample_db.embeddings
클러스터 의 네임스페이스 내의 Atlas UI 에서 확인하여 확인할 수 있습니다.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
다음 코드를 노트북에 붙여넣습니다.
다음 코드를 사용하여 새로운 데이터에서 임베딩을 생성합니다.
구체적으로, 이 코드는 사용자가 정의한 get_embedding
함수와 MongoDB PyMongo 드라이버를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 sample_db.embeddings
컬렉션으로 수집합니다.
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_db"] collection = db["embeddings"] # Sample data data = [ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission" ] # Ingest data into Atlas inserted_doc_count = 0 for text in data: embedding = get_embedding(text) collection.insert_one({ "text": text, "embedding": embedding }) inserted_doc_count += 1 print(f"Inserted {inserted_doc_count} documents.")
Inserted 3 documents.
연결 문자열을 지정합니다.
<connection-string>
을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.
참고
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
코드를 실행합니다.
클러스터의 sample_db.embeddings
컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 확인하여 벡터 임베딩을 확인할 수 있습니다.
(조건부) BSON 임베딩을 생성하는함수를 정의합니다.
노트북에 및 함수를 아직 로드하지 않은 get_embedding
generate_bson_vector
경우, 노트북에 이러한 함수를 로드하는 임베딩 함수 정의를 참조하세요.
기존 데이터를 로드합니다.
Atlas cluster 에서 데이터를 가져와서 노트북에 로드합니다. 다음 코드는 sample_airbnb.listingAndReviews
컬렉션 의 50
문서에서 summary
필드 가져옵니다.
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_airbnb"] collection = db["listingsAndReviews"] # Define a filter to exclude documents with null or empty 'summary' fields summary_filter = {"summary": {"$nin": [None, ""]}} # Get a subset of documents in the collection documents = collection.find(summary_filter, {'_id': 1, 'summary': 1}).limit(50)
Atlas cluster 로 임베딩을 생성, 변환 및 수집합니다.
다음 코드는 먼저 데이터에 float32
대한, int8
및 int1
임베딩을 생성한 다음, 해당 임베딩을 BSON,, float32
int8
하위 int1
유형으로 변환하고 마지막으로 임베딩을 다음에 업로드합니다. Atlas cluster.
참고
작업이 완료되는 데 몇 분 정도 걸릴 수 있습니다.
import pymongo from bson.binary import Binary updated_doc_count = 0 for doc in documents: summary = doc["summary"] # Generate float32 and other embeddings float32_embeddings = get_embedding(summary, precision="float32") int8_embeddings = get_embedding(summary, precision="int8") int1_embeddings = get_embedding(summary, precision="ubinary") # Initialize variables to store BSON vectors bson_float32_embeddings = generate_bson_vector(float32_embeddings, BinaryVectorDtype.FLOAT32) bson_int8_embeddings = generate_bson_vector(int8_embeddings, BinaryVectorDtype.INT8) bson_int1_embeddings = generate_bson_vector(int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Update each document with new embedding fields collection.update_one( {"_id": doc["_id"]}, {"$set": { "BSON-Float32-Embedding": bson_float32_embeddings, "BSON-Int8-Embedding": bson_int8_embeddings, "BSON-Int1-Embedding": bson_int1_embeddings }}, ) updated_doc_count += 1 print(f"Updated {updated_doc_count} documents.")
Updated 50 documents.
참고
이번 예시에서는 샘플 데이터의 sample_airbnb.listingsAndReviews
컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.
다음 코드를 노트북에 붙여넣습니다.
존 컬렉션의 필드에서 임베딩을 생성하려면 다음 코드를 사용하세요. 구체적으로 이 코드는 다음을 수행합니다.
Atlas 클러스터에 연결합니다.
sample_airbnb.listingsAndReviews
컬렉션에서summary
필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.정의한
get_embedding
함수를 사용하여 각 문서의summary
필드에서 임베딩을 생성합니다.MongoDB PyMongo 드라이버를 사용하여 임베딩 값이 포함된 새
embedding
필드로 각 문서를 업데이트합니다.
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_airbnb"] collection = db["listingsAndReviews"] # Filter to exclude null or empty summary fields filter = { "summary": {"$nin": [ None, "" ]} } # Get a subset of documents in the collection documents = collection.find(filter).limit(50) # Update each document with a new embedding field updated_doc_count = 0 for doc in documents: embedding = get_embedding(doc["summary"]) collection.update_one( { "_id": doc["_id"] }, { "$set": { "embedding": embedding } } ) updated_doc_count += 1 print(f"Updated {updated_doc_count} documents.")
Updated 50 documents.
연결 문자열을 지정합니다.
<connection-string>
을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.
참고
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
코드를 실행합니다.
Atlas UI 에서 컬렉션 으로 이동하고 문서 의 필드를 확장하면 생성되는 벡터 임베딩을 볼 수 있습니다.sample_airbnb.listingsAndReviews
쿼리에 대한 임베딩 만들기
이 섹션에서는 컬렉션의 벡터 임베딩을 인덱싱하고 샘플 벡터 검색 쿼리를 실행하는 데 사용하는 임베딩을 만듭니다.
쿼리를 실행하면 Atlas Vector Search는 벡터 검색 쿼리에서 임베딩과 거리가 가장 가까운 임베딩을 가진 문서를 반환합니다. 이는 의미상 유사함을 나타냅니다.
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embedding
필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct
으로 지정하는 sample_db.embeddings
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
다음 코드를 붙여넣어
DataService.cs
의DataService
클래스에CreateVectorIndex
함수를 추가합니다.DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_db"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("embeddings"); public async Task AddDocumentsAsync(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { try { var searchIndexView = Collection.SearchIndexes; var name = "vector_index"; var type = SearchIndexType.VectorSearch; var definition = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "type", "vector" }, { "path", "embedding" }, { "numDimensions", <dimensions> }, { "similarity", "dotProduct" } } } } }; var model = new CreateSearchIndexModel(name, type, definition); searchIndexView.CreateOne(model); Console.WriteLine($"New search index named {name} is building."); // Polling for index status Console.WriteLine("Polling to check if the index is ready. This may take up to a minute."); bool queryable = false; while (!queryable) { var indexes = searchIndexView.List(); foreach (var index in indexes.ToEnumerable()) { if (index["name"] == name) { queryable = index["queryable"].AsBoolean; } } if (!queryable) { Thread.Sleep(5000); } } Console.WriteLine($"{name} is ready for querying."); } catch (Exception e) { Console.WriteLine($"Exception: {e.Message}"); } } } 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을1024
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.Program.cs
에서 코드를 업데이트합니다.초기 문서를 채운 코드를 제거하고 다음 코드로 대체하여 인덱스 만듭니다.
Program.csusing MyCompany.Embeddings; var dataService = new DataService(); dataService.CreateVectorIndex(); 파일 저장한 다음, 프로젝트 컴파일하고 실행 인덱스 만듭니다.
dotnet run MyCompany.Embeddings New search index named vector_index is building. Polling to check if the index is ready. This may take up to a minute. vector_index is ready for querying.
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
다음 코드를 붙여넣어
DataService.cs
의DataService
클래스에PerformVectorQuery
함수를 추가합니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_db"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("embeddings"); public async Task AddDocumentsAsync(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { // Method details... } public List<BsonDocument>? PerformVectorQuery(float[] vector) { var vectorSearchStage = new BsonDocument { { "$vectorSearch", new BsonDocument { { "index", "vector_index" }, { "path", "embedding" }, { "queryVector", new BsonArray(vector) }, { "exact", true }, { "limit", 5 } } } }; var projectStage = new BsonDocument { { "$project", new BsonDocument { { "_id", 0 }, { "text", 1 }, { "score", new BsonDocument { { "$meta", "vectorSearchScore"} } } } } }; var pipeline = new[] { vectorSearchStage, projectStage }; return Collection.Aggregate<BsonDocument>(pipeline).ToList(); } } Program.cs
에서 코드를 업데이트합니다.벡터 인덱스 생성한 코드를 제거하고 쿼리 수행하는 코드를 추가합니다.
Program.csusing MongoDB.Bson; using MyCompany.Embeddings; var aiService = new AIService(); var queryString = "ocean tragedy"; var queryEmbedding = await aiService.GetEmbeddingsAsync([queryString]); if (!queryEmbedding.Any()) { Console.WriteLine("No embeddings found."); } else { var dataService = new DataService(); var matchingDocuments = dataService.PerformVectorQuery(queryEmbedding[queryString]); if (matchingDocuments == null) { Console.WriteLine("No documents matched the query."); } else { foreach (var document in matchingDocuments) { Console.WriteLine(document.ToJson()); } } } 파일 저장한 다음, 프로젝트 컴파일하고 실행 쿼리 수행합니다.
dotnet run MyCompany.Embeddings.csproj { "text" : "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "score" : 100.17414855957031 } { "text" : "Avatar: A marine is dispatched to the moon Pandora on a unique mission", "score" : 65.705635070800781 } { "text" : "The Lion King: Lion cub and future king Simba searches for his identity", "score" : 52.486415863037109 }
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embeddings
필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean
으로 지정하는 sample_airbnb.listingsAndReviews
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
다음 코드를 붙여넣어
DataService.cs
의DataService
클래스에CreateVectorIndex
함수를 추가합니다.DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_airbnb"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("listingsAndReviews"); public List<BsonDocument>? GetDocuments() { // Method details... } public async Task<long> AddEmbeddings(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { try { var searchIndexView = Collection.SearchIndexes; var name = "vector_index"; var type = SearchIndexType.VectorSearch; var definition = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "type", "vector" }, { "path", "embeddings" }, { "numDimensions", <dimensions> }, { "similarity", "dotProduct" } } } } }; var model = new CreateSearchIndexModel(name, type, definition); searchIndexView.CreateOne(model); Console.WriteLine($"New search index named {name} is building."); // Polling for index status Console.WriteLine("Polling to check if the index is ready. This may take up to a minute."); bool queryable = false; while (!queryable) { var indexes = searchIndexView.List(); foreach (var index in indexes.ToEnumerable()) { if (index["name"] == name) { queryable = index["queryable"].AsBoolean; } } if (!queryable) { Thread.Sleep(5000); } } Console.WriteLine($"{name} is ready for querying."); } catch (Exception e) { Console.WriteLine($"Exception: {e.Message}"); } } } 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을1024
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.Program.cs
에서 코드를 업데이트합니다.기존 문서에 임베딩을 추가한 코드를 제거하고 다음 코드로 대체하여 인덱스 만듭니다.
Program.csusing MyCompany.Embeddings; var dataService = new DataService(); dataService.CreateVectorIndex(); 파일 저장한 다음, 프로젝트 컴파일하고 실행 인덱스 만듭니다.
dotnet run MyCompany.Embeddings New search index named vector_index is building. Polling to check if the index is ready. This may take up to a minute. vector_index is ready for querying.
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
다음 코드를 붙여넣어
DataService.cs
의DataService
클래스에PerformVectorQuery
함수를 추가합니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_airbnb"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("listingsAndReviews"); public List<BsonDocument>? GetDocuments() { // Method details... } public async Task<long> AddEmbeddings(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { // Method details... } public List<BsonDocument>? PerformVectorQuery(float[] vector) { var vectorSearchStage = new BsonDocument { { "$vectorSearch", new BsonDocument { { "index", "vector_index" }, { "path", "embeddings" }, { "queryVector", new BsonArray(vector) }, { "exact", true }, { "limit", 5 } } } }; var projectStage = new BsonDocument { { "$project", new BsonDocument { { "_id", 0 }, { "summary", 1 }, { "score", new BsonDocument { { "$meta", "vectorSearchScore"} } } } } }; var pipeline = new[] { vectorSearchStage, projectStage }; return Collection.Aggregate<BsonDocument>(pipeline).ToList(); } } Program.cs
에서 코드를 업데이트합니다.벡터 인덱스 생성한 코드를 제거하고 쿼리 수행하는 코드를 추가합니다.
Program.csusing MongoDB.Bson; using MyCompany.Embeddings; var aiService = new AIService(); var queryString = "beach house"; var queryEmbedding = await aiService.GetEmbeddingsAsync([queryString]); if (!queryEmbedding.Any()) { Console.WriteLine("No embeddings found."); } else { var dataService = new DataService(); var matchingDocuments = dataService.PerformVectorQuery(queryEmbedding[queryString]); if (matchingDocuments == null) { Console.WriteLine("No documents matched the query."); } else { foreach (var document in matchingDocuments) { Console.WriteLine(document.ToJson()); } } } 파일 저장한 다음, 프로젝트 컴파일하고 실행 쿼리 수행합니다.
dotnet run MyCompany.Embeddings.csproj { "summary" : "Near to underground metro station. Walking distance to seaside. 2 floors 1 entry. Husband, wife, girl and boy is living.", "score" : 88.884147644042969 } { "summary" : "A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.", "score" : 86.136398315429688 } { "summary" : "Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.", "score" : 86.087783813476562 } { "summary" : "Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.", "score" : 85.689559936523438 } { "summary" : "Fully furnished 3+1 flat decorated with vintage style. Located at the heart of Moda/Kadıköy, close to seaside and also to the public transportation (tram, metro, ferry, bus stations) 10 minutes walk.", "score" : 85.614166259765625 }
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embedding
필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct
으로 지정하는 sample_db.embeddings
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
create-index.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.create-index.gopackage main import ( "context" "fmt" "log" "os" "time" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") indexName := "vector_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } indexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "embedding", NumDimensions: <dimensions>, Similarity: "dotProduct"}}, }, Options: opts, } log.Println("Creating the index.") searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("failed to create the search index: %v", err) } // Await the creation of the index. log.Println("Polling to confirm successful index creation.") searchIndexes := coll.SearchIndexes() var doc bson.Raw for doc == nil { cursor, err := searchIndexes.List(ctx, options.SearchIndexes().SetName(searchIndexName)) if err != nil { fmt.Errorf("failed to list search indexes: %w", err) } if !cursor.Next(ctx) { break } name := cursor.Current.Lookup("name").StringValue() queryable := cursor.Current.Lookup("queryable").Boolean() if name == searchIndexName && queryable { doc = cursor.Current } else { time.Sleep(5 * time.Second) } } log.Println("Name of Index Created: " + searchIndexName) } 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을1024
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.파일을 저장하고 다음 명령을 실행 합니다.
go run create-index.go 2024/10/09 17:38:51 Creating the index. 2024/10/09 17:38:52 Polling to confirm successful index creation. 2024/10/09 17:39:22 Name of Index Created: vector_index
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
vector-query.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type TextAndScore struct { Text string `bson:"text"` Score float32 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") query := "ocean tragedy" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embedding"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"text", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []TextAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score) } } vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type TextAndScore struct { Text string `bson:"text"` Score float64 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") query := "ocean tragedy" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embedding"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"text", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []TextAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score) } } 파일을 저장하고 다음 명령을 실행 합니다.
go run vector-query.go Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Score: 0.0042472864 Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Score: 0.0031167597 Text: The Lion King: Lion cub and future king Simba searches for his identity Score: 0.0024476869 go run vector-query.go Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Score: 0.4552372694015503 Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Score: 0.4050072133541107 Text: The Lion King: Lion cub and future king Simba searches for his identity Score: 0.35942140221595764
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embeddings
필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean
으로 지정하는 sample_airbnb.listingsAndReviews
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
create-index.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.create-index.gopackage main import ( "context" "fmt" "log" "os" "time" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") indexName := "vector_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } indexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "embeddings", NumDimensions: <dimensions>, Similarity: "dotProduct", Quantization: "scalar"}}, }, Options: opts, } log.Println("Creating the index.") searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("failed to create the search index: %v", err) } // Await the creation of the index. log.Println("Polling to confirm successful index creation.") searchIndexes := coll.SearchIndexes() var doc bson.Raw for doc == nil { cursor, err := searchIndexes.List(ctx, options.SearchIndexes().SetName(searchIndexName)) if err != nil { fmt.Errorf("failed to list search indexes: %w", err) } if !cursor.Next(ctx) { break } name := cursor.Current.Lookup("name").StringValue() queryable := cursor.Current.Lookup("queryable").Boolean() if name == searchIndexName && queryable { doc = cursor.Current } else { time.Sleep(5 * time.Second) } } log.Println("Name of Index Created: " + searchIndexName) } 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을1024
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.파일을 저장하고 다음 명령을 실행 합니다.
go run create-index.go 2024/10/10 10:03:12 Creating the index. 2024/10/10 10:03:13 Polling to confirm successful index creation. 2024/10/10 10:03:44 Name of Index Created: vector_index
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
vector-query.go
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type SummaryAndScore struct { Summary string `bson:"summary"` Score float32 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") query := "beach house" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embeddings"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"summary", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []SummaryAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to SummaryAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Summary: %v\nScore: %v\n", doc.Summary, doc.Score) } } vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type SummaryAndScore struct { Summary string `bson:"summary"` Score float64 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") query := "beach house" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embeddings"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"summary", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []SummaryAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to SummaryAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Summary: %v\nScore: %v\n", doc.Summary, doc.Score) } } 파일을 저장하고 다음 명령을 실행 합니다.
go run vector-query.go Summary: Near to underground metro station. Walking distance to seaside. 2 floors 1 entry. Husband, wife, girl and boy is living. Score: 0.0045180833 Summary: A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door. Score: 0.004480799 Summary: Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway. Score: 0.0042421296 Summary: Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily. Score: 0.004227752 Summary: A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses. Score: 0.0042201905 go run vector-query.go Summary: A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses. Score: 0.4832950830459595 Summary: Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily. Score: 0.48093676567077637 Summary: THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!! Score: 0.4629695415496826 Summary: A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door. Score: 0.45800843834877014 Summary: The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2. Score: 0.45398443937301636
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embedding
필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct
으로 지정하는 sample_db.embeddings
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
CreateIndex.java
이라는 파일 을 만들고 다음 코드를 붙여넣습니다.CreateIndex.javaimport com.mongodb.MongoException; import com.mongodb.client.ListSearchIndexesIterable; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.SearchIndexModel; import com.mongodb.client.model.SearchIndexType; import org.bson.Document; import org.bson.conversions.Bson; import java.util.Collections; import java.util.List; public class CreateIndex { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_db"); MongoCollection<Document> collection = database.getCollection("embeddings"); // define the index details String indexName = "vector_index"; int dimensionsHuggingFaceModel = 1024; int dimensionsOpenAiModel = 1536; Bson definition = new Document( "fields", Collections.singletonList( new Document("type", "vector") .append("path", "embedding") .append("numDimensions", <dimensions>) // replace with var for the model used .append("similarity", "dotProduct"))); // define the index model using the specified details SearchIndexModel indexModel = new SearchIndexModel( indexName, definition, SearchIndexType.vectorSearch()); // Create the index using the model try { List<String> result = collection.createSearchIndexes(Collections.singletonList(indexModel)); System.out.println("Successfully created a vector index named: " + result); } catch (Exception e) { throw new RuntimeException(e); } // Wait for Atlas to build the index and make it queryable System.out.println("Polling to confirm the index has completed building."); System.out.println("It may take up to a minute for the index to build before you can query using it."); ListSearchIndexesIterable<Document> searchIndexes = collection.listSearchIndexes(); Document doc = null; while (doc == null) { try (MongoCursor<Document> cursor = searchIndexes.iterator()) { if (!cursor.hasNext()) { break; } Document current = cursor.next(); String name = current.getString("name"); boolean queryable = current.getBoolean("queryable"); if (name.equals(indexName) && queryable) { doc = current; } else { Thread.sleep(500); } } catch (Exception e) { throw new RuntimeException(e); } } System.out.println(indexName + " index is ready to query"); } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } <dimensions>
자리 표시자 값을 사용한 모델에 적합한 변수로 바꿉니다.dimensionsHuggingFaceModel
:1024
차원("mixedbread-ai/mxbai-embed-large-v1" 모델)dimensionsOpenAiModel
:1536
차원("text-embedding-3-small" 모델)
참고
차원 수는 임베딩을 생성하는 데 사용된 모델에 따라 결정됩니다. 다른 모델을 사용하도록 이 코드를 수정하는 경우
numDimensions
에 올바른 값을 전달해야 합니다. 임베딩 모델 선택 섹션도 참조하세요.파일을 저장하고 실행합니다. 출력은 다음과 같습니다.
Successfully created a vector index named: [vector_index] Polling to confirm the index has completed building. It may take up to a minute for the index to build before you can query using it. vector_index index is ready to query
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
VectorQuery.java
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
VectorQuery.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.search.FieldSearchPath; import org.bson.BsonArray; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.List; import static com.mongodb.client.model.Aggregates.project; import static com.mongodb.client.model.Aggregates.vectorSearch; import static com.mongodb.client.model.Projections.exclude; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaVectorSearchScore; import static com.mongodb.client.model.search.SearchPath.fieldPath; import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions; import static java.util.Arrays.asList; public class VectorQuery { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_db"); MongoCollection<Document> collection = database.getCollection("embeddings"); // define $vectorSearch query options String query = "ocean tragedy"; EmbeddingProvider embeddingProvider = new EmbeddingProvider(); BsonArray embeddingBsonArray = embeddingProvider.getEmbedding(query); List<Double> embedding = new ArrayList<>(); for (BsonValue value : embeddingBsonArray.stream().toList()) { embedding.add(value.asDouble().getValue()); } // define $vectorSearch pipeline String indexName = "vector_index"; FieldSearchPath fieldSearchPath = fieldPath("embedding"); int limit = 5; List<Bson> pipeline = asList( vectorSearch( fieldSearchPath, embedding, indexName, limit, exactVectorSearchOptions() ), project( fields(exclude("_id"), include("text"), metaVectorSearchScore("score")))); // run query and print results List<Document> results = collection.aggregate(pipeline).into(new ArrayList<>()); if (results.isEmpty()) { System.out.println("No results found."); } else { results.forEach(doc -> { System.out.println("Text: " + doc.getString("text")); System.out.println("Score: " + doc.getDouble("score")); }); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } 파일 을 저장하고 실행 합니다. 출력은 사용한 모델에 따라 다음 중 하나와 유사합니다.
Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Score: 0.004247286356985569 Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Score: 0.003116759704425931 Text: The Lion King: Lion cub and future king Simba searches for his identity Score: 0.002447686856612563 Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Score: 0.45522359013557434 Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Score: 0.4049977660179138 Text: The Lion King: Lion cub and future king Simba searches for his identity Score: 0.35942474007606506
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embeddings
필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean
으로 지정하는 sample_airbnb.listingsAndReviews
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
CreateIndex.java
이라는 파일 을 만들고 다음 코드를 붙여넣습니다.CreateIndex.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.ListSearchIndexesIterable; import com.mongodb.client.MongoCursor; import com.mongodb.client.model.SearchIndexModel; import com.mongodb.client.model.SearchIndexType; import org.bson.Document; import org.bson.conversions.Bson; import java.util.Collections; import java.util.List; public class CreateIndex { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_airbnb"); MongoCollection<Document> collection = database.getCollection("listingsAndReviews"); // define the index details String indexName = "vector_index"; int dimensionsHuggingFaceModel = 1024; int dimensionsOpenAiModel = 1536; Bson definition = new Document( "fields", Collections.singletonList( new Document("type", "vector") .append("path", "embeddings") .append("numDimensions", <dimensions>) // replace with var for the model used .append("similarity", "dotProduct") .append('quantization', "scalar"))); // define the index model using the specified details SearchIndexModel indexModel = new SearchIndexModel( indexName, definition, SearchIndexType.vectorSearch()); // create the index using the model try { List<String> result = collection.createSearchIndexes(Collections.singletonList(indexModel)); System.out.println("Successfully created a vector index named: " + result); System.out.println("It may take up to a minute for the index to build before you can query using it."); } catch (Exception e) { throw new RuntimeException(e); } // wait for Atlas to build the index and make it queryable System.out.println("Polling to confirm the index has completed building."); ListSearchIndexesIterable<Document> searchIndexes = collection.listSearchIndexes(); Document doc = null; while (doc == null) { try (MongoCursor<Document> cursor = searchIndexes.iterator()) { if (!cursor.hasNext()) { break; } Document current = cursor.next(); String name = current.getString("name"); boolean queryable = current.getBoolean("queryable"); if (name.equals(indexName) && queryable) { doc = current; } else { Thread.sleep(500); } } catch (Exception e) { throw new RuntimeException(e); } } System.out.println(indexName + " index is ready to query"); } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } <dimensions>
자리 표시자 값을 사용한 모델에 적합한 변수로 바꿉니다.dimensionsHuggingFaceModel
:1024
차원(오픈 소스)dimensionsOpenAiModel
:1536
차원
참고
차원 수는 임베딩을 생성하는 데 사용된 모델에 따라 결정됩니다. 다른 모델을 사용하는 경우
numDimensions
에 올바른 값을 전달해야 합니다. 임베딩 모델 선택 섹션도 참조하세요.파일을 저장하고 실행합니다. 출력은 다음과 같습니다.
Successfully created a vector index named: [vector_index] Polling to confirm the index has completed building. It may take up to a minute for the index to build before you can query using it. vector_index index is ready to query
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
VectorQuery.java
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
VectorQuery.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.search.FieldSearchPath; import org.bson.BsonArray; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.List; import static com.mongodb.client.model.Aggregates.project; import static com.mongodb.client.model.Aggregates.vectorSearch; import static com.mongodb.client.model.Projections.exclude; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaVectorSearchScore; import static com.mongodb.client.model.search.SearchPath.fieldPath; import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions; import static java.util.Arrays.asList; public class VectorQuery { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_airbnb"); MongoCollection<Document> collection = database.getCollection("listingsAndReviews"); // define the query and get the embedding String query = "beach house"; EmbeddingProvider embeddingProvider = new EmbeddingProvider(); BsonArray embeddingBsonArray = embeddingProvider.getEmbedding(query); List<Double> embedding = new ArrayList<>(); for (BsonValue value : embeddingBsonArray.stream().toList()) { embedding.add(value.asDouble().getValue()); } // define $vectorSearch pipeline String indexName = "vector_index"; FieldSearchPath fieldSearchPath = fieldPath("embeddings"); int limit = 5; List<Bson> pipeline = asList( vectorSearch( fieldSearchPath, embedding, indexName, limit, exactVectorSearchOptions()), project( fields(exclude("_id"), include("summary"), metaVectorSearchScore("score")))); // run query and print results List<Document> results = collection.aggregate(pipeline).into(new ArrayList<>()); if (results.isEmpty()) { System.out.println("No results found."); } else { results.forEach(doc -> { System.out.println("Summary: " + doc.getString("summary")); System.out.println("Score: " + doc.getDouble("score")); }); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } 파일 을 저장하고 실행 합니다. 출력은 사용한 모델에 따라 다음 중 하나와 유사합니다.
Summary: Near to underground metro station. Walking distance to seaside. 2 floors 1 entry. Husband, wife, girl and boy is living. Score: 0.004518083296716213 Summary: A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door. Score: 0.0044807991944253445 Summary: Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway. Score: 0.004242129623889923 Summary: Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily. Score: 0.004227751865983009 Summary: A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses. Score: 0.004220190457999706 Summary: A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses. Score: 0.4832950830459595 Summary: Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily. Score: 0.48092085123062134 Summary: THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!! Score: 0.4629460275173187 Summary: A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door. Score: 0.4581468403339386 Summary: The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2. Score: 0.45398443937301636
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embedding
필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct
으로 지정하는 sample_db.embeddings
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
create-index.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.create-index.jsimport { MongoClient } from 'mongodb'; // connect to your Atlas deployment const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { const database = client.db("sample_db"); const collection = database.collection("embeddings"); // define your Atlas Vector Search index const index = { name: "vector_index", type: "vectorSearch", definition: { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": <dimensions> } ] } } // run the helper method const result = await collection.createSearchIndex(index); console.log(result); } finally { await client.close(); } } run().catch(console.dir); 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을768
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.파일을 저장하고 다음 명령을 실행 합니다.
node --env-file=.env create-index.js
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
vector-query.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
vector-query.jsimport { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // MongoDB connection URI and options const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { // Connect to the MongoDB client await client.connect(); // Specify the database and collection const database = client.db("sample_db"); const collection = database.collection("embeddings"); // Generate embedding for the search query const queryEmbedding = await getEmbedding("ocean tragedy"); // Define the sample vector search pipeline const pipeline = [ { $vectorSearch: { index: "vector_index", queryVector: queryEmbedding, path: "embedding", exact: true, limit: 5 } }, { $project: { _id: 0, text: 1, score: { $meta: "vectorSearchScore" } } } ]; // run pipeline const result = collection.aggregate(pipeline); // print results for await (const doc of result) { console.dir(JSON.stringify(doc)); } } finally { await client.close(); } } run().catch(console.dir); 파일을 저장하고 다음 명령을 실행 합니다.
node --env-file=.env vector-query.js '{"text":"Titanic: The story of the 1912 sinking of the largest luxury liner ever built","score":0.5103757977485657}' '{"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4616812467575073}' '{"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.4115804433822632}' node --env-file=.env vector-query.js {"text":"Titanic: The story of the 1912 sinking of the largest luxury liner ever built","score":0.4551968574523926} {"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4050074517726898} {"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.3594386577606201}
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
embedding
필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean
으로 지정하는 sample_airbnb.listingsAndReviews
컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.
create-index.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.create-index.jsimport { MongoClient } from 'mongodb'; // connect to your Atlas deployment const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { const database = client.db("sample_airbnb"); const collection = database.collection("listingsAndReviews"); // Define your Atlas Vector Search index const index = { name: "vector_index", type: "vectorSearch", definition: { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": <dimensions>, "quantization": "scalar" } ] } } // Call the method to create the index const result = await collection.createSearchIndex(index); console.log(result); } finally { await client.close(); } } run().catch(console.dir); 오픈 소스 모델을 사용한 경우
<dimensions>
자리 표시자 값을768
(으)로 바꾸고, OpenAI의 모델을 사용한 경우1536
(으)로 바꿉니다.파일을 저장하고 다음 명령을 실행 합니다.
node --env-file=.env create-index.js
참고
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
vector-query.js
라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
vector-query.jsimport { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // MongoDB connection URI and options const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { // Connect to the MongoDB client await client.connect(); // Specify the database and collection const database = client.db("sample_airbnb"); const collection = database.collection("listingsAndReviews"); // Generate embedding for the search query const queryEmbedding = await getEmbedding("beach house"); // Define the sample vector search pipeline const pipeline = [ { $vectorSearch: { index: "vector_index", queryVector: queryEmbedding, path: "embedding", exact: true, limit: 5 } }, { $project: { _id: 0, summary: 1, score: { $meta: "vectorSearchScore" } } } ]; // run pipeline const result = collection.aggregate(pipeline); // print results for await (const doc of result) { console.dir(JSON.stringify(doc)); } } finally { await client.close(); } } run().catch(console.dir); 파일을 저장하고 다음 명령을 실행 합니다.
node --env-file=.env vector-query.js '{"summary":"Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.","score":0.5334879159927368}' '{"summary":"A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.","score":0.5240535736083984}' '{"summary":"The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.","score":0.5232879519462585}' '{"summary":"Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.","score":0.5186381340026855}' '{"summary":"A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.","score":0.5078228116035461}' node --env-file=.env vector-query.js {"summary": "A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.", "score": 0.483333021402359} {"summary": "Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.", "score": 0.48092877864837646} {"summary": "THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!!", "score": 0.46294474601745605} {"summary": "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", "score": 0.4580020606517792} {"summary": "The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.", "score": 0.45400717854499817}
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
다음 코드를 노트북에 붙여넣습니다.
이 코드는 컬렉션 에 다음을 지정하는 인덱스 생성합니다.
BSON-Float32-Embedding
,BSON-Int8-Embedding
및BSON-Int1-Embedding
필드를 벡터 유형 필드로 사용합니다.euclidean
int1
임베딩의 경우 유사성 함수로,dotProduct
을float32
및int8
임베딩의 경우 유사성 유형으로 사용합니다.768
임베딩의 차원 수입니다.
from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "BSON-Float32-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int8-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int1-Embedding", "similarity": "euclidean", "numDimensions": 768 } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) 코드를 실행합니다.
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
다음 코드를 노트북에 붙여넣습니다.
이 코드는 컬렉션 에 인덱스 생성하고 필드
embedding
벡터dotProduct
유형으로, 유사성 함수를, 차원 수를 로1536
지정합니다. 또한 필드 의 벡터에 대한 자동 스칼라 양자화를 활성화하여embedding
벡터 데이터를 효율적으로 처리 .from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": 1536, "quantization": "scalar" } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) 코드를 실행합니다.
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리 에 대한 임베딩을 만든 다음 쿼리 실행 .
벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
쿼리 임베딩을 BSON,
float32
int8
및int1
벡터 하위 유형으로 변환합니다.임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
참고
쿼리 완료되는 데 시간이 걸릴 수 있습니다.
import pymongo from bson.binary import Binary # Prepare your query query_text = "ocean tragedy" # Generate embedding for the search query query_float32_embeddings = get_embedding(query_text, precision="float32") query_int8_embeddings = get_embedding(query_text, precision="int8") query_int1_embeddings = get_embedding(query_text, precision="ubinary") # Convert each embedding to BSON format query_bson_float32_embeddings = generate_bson_vector(query_float32_embeddings, BinaryVectorDtype.FLOAT32) query_bson_int8_embeddings = generate_bson_vector(query_int8_embeddings, BinaryVectorDtype.INT8) query_bson_int1_embeddings = generate_bson_vector(query_int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Define vector search pipeline for each precision pipelines = [] for query_embedding, path in zip( [query_bson_float32_embeddings, query_bson_int8_embeddings, query_bson_int1_embeddings], ["BSON-Float32-Embedding", "BSON-Int8-Embedding", "BSON-Int1-Embedding"] ): pipeline = [ { "$vectorSearch": { "index": "vector_index", # Adjust if necessary "queryVector": query_embedding, "path": path, "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "data": 1, "score": { "$meta": "vectorSearchScore" } } } ] pipelines.append(pipeline) # Execute the search for each precision for pipeline in pipelines: print(f"Results for {pipeline[0]['$vectorSearch']['path']}:") results = collection.aggregate(pipeline) # Print results for i in results: print(i)
Results for BSON-Float32-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.7661113739013672} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.7050272822380066} {'data': 'The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.', 'score': 0.7024770379066467} {'data': 'Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.', 'score': 0.7011005282402039} {'data': 'E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home.', 'score': 0.6877288818359375} Results for BSON-Int8-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.5} {'data': 'The Lion King: Lion cub and future king Simba searches for his identity', 'score': 0.5} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.5} {'data': "Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious.", 'score': 0.5} {'data': 'The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son.', 'score': 0.5} Results for BSON-Int1-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.671875} {'data': 'The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.', 'score': 0.6484375} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.640625} {'data': 'Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love.', 'score': 0.6145833134651184} {'data': 'Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.', 'score': 0.61328125}
# Generate embedding for the search query query_embedding = get_embedding("ocean tragedy") # Sample vector search pipeline pipeline = [ { "$vectorSearch": { "index": "vector_index", "queryVector": query_embedding, "path": "embedding", "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "text": 1, "score": { "$meta": "vectorSearchScore" } } } ] # Execute the search results = collection.aggregate(pipeline) # Print results for i in results: print(i)
{"text":"Titanic: The story of the 1912 sinking of the largest luxury liner ever built","score":0.4551968574523926} {"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4050074517726898} {"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.3594386577606201}
Atlas Vector Search 인덱스를 정의합니다.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
다음 코드를 노트북에 붙여넣습니다.
이 코드는 컬렉션 에 다음을 지정하는 인덱스 생성합니다.
BSON-Float32-Embedding
,BSON-Int8-Embedding
및BSON-Int1-Embedding
필드를 벡터 유형 필드로 사용합니다.euclidean
int1
임베딩의 경우 유사성 함수로,dotProduct
을float32
및int8
임베딩의 경우 유사성 유형으로 사용합니다.768
임베딩의 차원 수입니다.
from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "BSON-Float32-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int8-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int1-Embedding", "similarity": "euclidean", "numDimensions": 768 } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) 코드를 실행합니다.
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.
다음 코드를 노트북에 붙여넣습니다.
이 코드는 컬렉션 에 인덱스 생성하고 필드
embedding
벡터dotProduct
유형으로, 유사성 함수를, 차원 수를 로1536
지정합니다. 또한 필드 의 벡터에 대한 자동 스칼라 양자화를 활성화하여embedding
벡터 데이터를 효율적으로 처리 .from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": 1536, "quantization": "scalar" } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) 코드를 실행합니다.
인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.
자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.
벡터 검색 쿼리에 대한 임베딩을 생성하고 쿼리를 실행 합니다.
벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
쿼리 임베딩을 BSON,
float32
int8
및int1
벡터 하위 유형으로 변환합니다.임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
import pymongo from bson.binary import Binary # Prepare your query query_text = "beach house" # Generate embedding for the search query query_float32_embeddings = get_embedding(query_text, precision="float32") query_int8_embeddings = get_embedding(query_text, precision="int8") query_int1_embeddings = get_embedding(query_text, precision="ubinary") # Convert each embedding to BSON format query_bson_float32_embeddings = generate_bson_vector(query_float32_embeddings, BinaryVectorDtype.FLOAT32) query_bson_int8_embeddings = generate_bson_vector(query_int8_embeddings, BinaryVectorDtype.INT8) query_bson_int1_embeddings = generate_bson_vector(query_int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Define vector search pipeline for each precision pipelines = [] for query_embedding, path in zip( [query_bson_float32_embeddings, query_bson_int8_embeddings, query_bson_int1_embeddings], ["BSON-Float32-Embedding", "BSON-Int8-Embedding", "BSON-Int1-Embedding"] ): pipeline = [ { "$vectorSearch": { "index": "vector_index", # Adjust if necessary "queryVector": query_embedding, "path": path, "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "summary": 1, "score": { "$meta": "vectorSearchScore" } } } ] pipelines.append(pipeline) # Execute the search for each precision for pipeline in pipelines: print(f"Results for {pipeline[0]['$vectorSearch']['path']}:") results = collection.aggregate(pipeline) # Print results for i in results: print(i)
Results for BSON-Float32-Embedding: {'summary': 'Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.', 'score': 0.7847104072570801} {'summary': 'The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.', 'score': 0.7780507802963257} {'summary': "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", 'score': 0.7723637223243713} {'summary': 'Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.', 'score': 0.7665778398513794} {'summary': 'A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.', 'score': 0.7593404650688171} Results for BSON-Int8-Embedding: {'summary': 'Fantastic duplex apartment with three bedrooms, located in the historic area of Porto, Ribeira (Cube) - UNESCO World Heritage Site. Centenary building fully rehabilitated, without losing their original character.', 'score': 0.5} {'summary': 'One bedroom + sofa-bed in quiet and bucolic neighbourhood right next to the Botanical Garden. Small garden, outside shower, well equipped kitchen and bathroom with shower and tub. Easy for transport with many restaurants and basic facilities in the area.', 'score': 0.5} {'summary': "A short distance from Honolulu's billion dollar mall, and the same distance to Waikiki. Parking included. A great location that work perfectly for business, education, or simple visit. Experience Yacht Harbor views and 5 Star Hilton Hawaiian Village.", 'score': 0.5} {'summary': 'Here exists a very cozy room for rent in a shared 4-bedroom apartment. It is located one block off of the JMZ at Myrtle Broadway. The neighborhood is diverse and appeals to a variety of people.', 'score': 0.5} {'summary': 'Quarto com vista para a Lagoa Rodrigo de Freitas, cartão postal do Rio de Janeiro. Linda Vista. 1 Quarto e 1 banheiro Amplo, arejado, vaga na garagem. Prédio com piscina, sauna e playground. Fácil acesso, próximo da praia e shoppings.', 'score': 0.5} Results for BSON-Int1-Embedding: {'summary': 'Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.', 'score': 0.6901041865348816} {'summary': 'Cozy and comfortable apartment. Ideal for families and vacations. 3 bedrooms, 2 of them suites. Located 20-min walk to the beach and close to the Rio 2016 Olympics Venues. Situated in a modern and secure condominium, with many entertainment available options around.', 'score': 0.6731770634651184} {'summary': "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", 'score': 0.6731770634651184} {'summary': 'The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.', 'score': 0.671875} {'summary': 'THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!!', 'score': 0.6705729365348816}
벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.
예를 들어 이 코드는 다음을 수행합니다.
정의한 임베딩 함수를 호출하여 샘플 쿼리 임베딩을 만듭니다.
임베딩을
queryVector
필드 에 전달하고 집계 파이프라인 에서 검색 할 경로를 지정합니다.임베딩에 대해 ENN
$vectorSearch
검색 수행하기 위해 파이프라인 에서 단계를 지정합니다.컬렉션 에 저장된 임베딩에 대해 샘플 벡터 검색 쿼리 실행합니다.
의미적으로 유사한 문서를 관련성 및 벡터 검색 점수 순으로 반환합니다.
# Generate embedding for the search query query_embedding = get_embedding("beach house") # Sample vector search pipeline pipeline = [ { "$vectorSearch": { "index": "vector_index", "queryVector": query_embedding, "path": "embedding", "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "summary": 1, "score": { "$meta": "vectorSearchScore" } } } ] # Execute the search results = collection.aggregate(pipeline) # Print results for i in results: print(i)
{"summary": "A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.", "score": 0.483333021402359} {"summary": "Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.", "score": 0.48092877864837646} {"summary": "THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!!", "score": 0.46294474601745605} {"summary": "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", "score": 0.4580020606517792} {"summary": "The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.", "score": 0.45400717854499817}
고려 사항
벡터 임베딩을 생성할 때 다음 요소를 고려하세요.
임베딩 생성 방법 선택
벡터 임베딩을 생성하려면 임베딩 모델을 사용해야 합니다. 임베딩 모델은 데이터를 임베딩으로 변환하는 데 사용하는 알고리즘입니다. 다음 방법 중 하나를 선택하여 임베딩 모델에 연결하고 벡터 임베딩을 생성할 수 있습니다.
메서드 | 설명 |
---|---|
오픈소스 모델 로드 | 독점 임베딩 모델에 대한 API 키가 없는 경우 애플리케이션에서 로컬로 오픈 소스 임베딩 모델을 로드합니다. |
독점 모델 사용 | 대부분의 AI 제공자는 벡터 임베딩을 생성하는 데 사용할 수 있는 독점 임베딩 모델용 API를 제공합니다. |
통합 활용 | Atlas Vector Search를 오픈 소스 프레임워크 및 AI 서비스와 통합하여 오픈 소스 및 독점 임베딩 모델 모두에 빠르게 연결하고 Atlas Vector Search를 위한 벡터 임베딩을 생성할 수 있습니다. 자세한 내용은 벡터 검색과 AI 기술 통합을 참조하세요. |
임베딩 모델 선택
선택한 임베딩 모델은 쿼리 결과에 영향을 미치며 Atlas Vector Search 인덱스에서 지정하는 차원 수를 결정합니다. 각 모델은 데이터와 사용 사례에 따라 서로 다른 이점을 제공합니다.
널리 사용되는 임베딩 모델 목록은 MTEB(대규모 텍스트 임베딩 벤치마크)를 참조하세요. 이 목록은 다양한 오픈 소스 및 독점 텍스트 임베딩 모델을 다룬 인사이트를 제공하며 사용 사례, 모델 유형 및 특정 모델 메트릭에 따라 모델을 필터링할 수 있습니다.
Atlas Vector Search에 대한 임베딩 모델을 선택할 때 다음 지표를 고려하세요.
임베딩 차원: 벡터 임베딩의 길이입니다.
임베딩 크기가 작을수록 저장 효율이 높고, 임베딩 크기가 클수록 데이터의 미묘한 관계를 더 잘 포착할 수 있습니다. 선택하는 모델은 효율성과 복잡성 사이의 균형을 유지해야 합니다.
모델 크기: 모델의 크기(기가바이트)입니다.
더 큰 모델은 성능이 뛰어나지만 Atlas Vector Search를 프로덕션으로 확장할 때 더 많은 컴퓨팅 자원이 필요합니다.
조회 평균: 조회 시스템의 성능을 측정하는 점수입니다.
점수가 높을수록 모델이 검색된 결과 목록에서 관련 문서의 순위를 더 높게 매기는 데 더 적합하다는 것을 나타냅니다. 이 점수는 RAG 애플리케이션에 대한 모델을 선택할 때 중요합니다.
임베딩 유효성 검사
임베딩이 올바르고 최적화된지 확인하려면 다음 전략을 고려하세요.
함수와 스크립트를 테스트합니다.
임베딩을 생성하려면 시간과 계산 리소스가 필요합니다. 대규모 데이터 세트 또는 컬렉션에서 임베딩을 생성하기 전에 임베딩 함수 또는 스크립트가 데이터의 작은 하위 집합에서 예상대로 작동하는지 테스트합니다.
임베딩을 일괄적으로 생성합니다.
대규모 데이터 세트나 문서가 많은 컬렉션 에서 임베딩을 생성하려는 경우, 메모리 문제를 방지하고 성능을 최적화하려면 배치로 생성하세요.
성능을 평가합니다.
테스트 쿼리를 실행하여 검색 결과가 관련성이 있고 정확하게 순위가 매겨졌는지 확인합니다.
결과를 평가하고 인덱스 및 쿼리의 성능을 미세 조정하는 방법에 학습 보려면 쿼리 결과의 정확도를 측정하고 벡터 검색 성능을 개선하는 방법을 참조하세요.
문제 해결
임베딩에 문제가 발생하는 경우 다음 전략을 고려하세요.
환경을 확인합니다.
필요한 종속성이 설치되어 있고 최신 상태인지 확인합니다. 라이브러리 버전이 충돌하면 예기치 않은 동작이 발생할 수 있습니다. 새 환경을 만들고 필요한 패키지만 설치하여 충돌이 없는지 확인합니다.
참고
Colab을 사용하는 경우 노트북 세션의 IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요.
메모리 사용량을 모니터링합니다.
성능 문제가 발생하면 RAM, CPU, 디스크 사용량을 확인하여 잠재적인 병목 현상을 파악하세요. Colab이나 Jupyter Notebooks와 같은 호스팅 환경에서는 인스턴스에 충분한 리소스가 프로비저닝되어 있는지 확인하고 필요한 경우 인스턴스를 업그레이드하세요.
일관적인 크기 보장
Atlas Vector Search 인덱스 정의가 Atlas 에 저장된 임베딩의 크기와 일치하고 쿼리 임베딩이 인덱싱된 임베딩의 크기와 일치하는지 확인합니다. 그렇지 않으면 벡터 검색 쿼리를 실행 때 오류가 발생할 수 있습니다.
특정 문제를 해결하려면 문제 해결을 참조하세요.
다음 단계
Atlas Vector Search로 임베딩을 만들고 임베딩을 쿼리하는 방법을 익혔다면, 검색 증강 생성(RAG)을 구현하여 생성형 인공지능 애플리케이션 빌드를 시작하세요.
Atlas 에서 벡터를 효율적으로 저장 하고 수집하기 위해 임베딩을 BSON 벡터로 변환할 수도 있습니다. 학습 내용은 사전 양자화된 벡터 수집 방법을 참조하세요.