Docs Menu
Docs Home
/
Atlas
/

벡터 임베딩을 만드는 방법

이 페이지의 내용

  • 시작하기
  • 전제 조건
  • 임베딩 모델 사용
  • 데이터에서 임베딩 생성
  • 쿼리에 대한 임베딩 만들기
  • 고려 사항
  • 임베딩 생성 방법 선택
  • 임베딩 모델 선택
  • 벡터 압축
  • 임베딩 유효성 검사
  • 다음 단계

벡터 임베딩을 다른 데이터와 함께 Atlas에 저장할 수 있습니다. 이러한 임베딩은 데이터 내의 의미 있는 관계를 포착하여 Atlas Vector Search에서 시맨틱 검색을 수행하고 RAG를 구현할 수 있도록 합니다.

다음 튜토리얼을 통해 Atlas Vector Search 를 사용하여 벡터 임베딩을 만들고 쿼리 하는 방법을 학습 보세요. 구체적으로 다음 조치를 수행합니다.

  1. 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다.

  2. 데이터에서 임베딩을 생성하여 Atlas에 저장합니다.

  3. 검색어에서 임베딩을 생성하고 벡터 검색 쿼리를 실행합니다.

프로덕션 애플리케이션의 경우 일반적으로 벡터 임베딩을 생성하는 스크립트 를 쓰기 (write) 합니다. 이 페이지의 샘플 코드로 시작하여 사용 사례 에 맞게 사용자 지정할 수 있습니다.


언어 선택 드롭다운 메뉴를 사용하여 이 페이지에 있는 예시의 언어를 설정합니다.

이 튜토리얼의 실행 가능한 버전을 Python 노트북으로 작업하세요.

이 튜토리얼을 완료하려면 다음 조건을 충족해야 합니다.

  • Atlas 계정, 클러스터에서 MongoDB 버전 6.0.11, 7.0.2 또는 그 이상 실행(RC 포함). IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 자세히 알아보려면 클러스터 생성을 참조하세요.

  • C# 프로젝트를 실행하기 위한 터미널 및 코드 편집기.

  • .NET 8.0 이상이 설치되었습니다.

  • Hugging Face Access Token 또는 OpenAI API 키입니다.

  • Atlas 계정, 클러스터에서 MongoDB 버전 6.0.11, 7.0.2 또는 그 이상 실행( RC 포함). IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 자세히 알아보려면 클러스터 생성을 참조하세요.

  • Go 프로젝트를 실행하기 위한 터미널 및 코드 편집기입니다.

  • Go가 설치되었습니다.

  • Hugging Face Access Token 또는 OpenAI API 키입니다.

  • Atlas 계정, 클러스터에서 MongoDB 버전 6.0.11, 7.0.2 또는 그 이상 실행( RC 포함). IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 자세히 알아보려면 클러스터 생성을 참조하세요.

  • Java Development Kit (JDK) 버전 8 이상.

  • Java 애플리케이션 설정하다 하고 실행 위한 환경입니다. IntelliJ IDEA 또는 Eclipse IDE와 같은 통합 개발 환경(IDE)을 사용하여 프로젝트 를 빌드 하고 실행 하도록 Maven 또는 Gradle을 구성하는 것이 좋습니다.

  • 다음 중 하나입니다.

    • 읽기 액세스 이 있는 Hugging face 액세스 토큰

    • OpenAI API 키입니다. API 요청에 사용할 수 있는 크레딧이 있는 OpenAI 계정이 있어야 합니다. OpenAI 계정 등록에 대한 자세한 내용은 OpenAI API 웹사이트를 참조하세요.

  • Atlas 계정, 클러스터에서 MongoDB 버전 6.0.11, 7.0.2 또는 그 이상 실행( RC 포함). IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 자세히 알아보려면 클러스터 생성을 참조하세요.

  • Node.js 프로젝트를 실행하기 위한 터미널 및 코드 편집기입니다.

  • npm 및 Node.js 설치되었습니다.

  • OpenAI 모델을 사용하는 경우 OpenAI API 키가 있어야 합니다.

  • Atlas 계정, 클러스터에서 MongoDB 버전 6.0.11, 7.0.2 또는 그 이상 실행( RC 포함). IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요. 자세히 알아보려면 클러스터 생성을 참조하세요.

  • VS Code 또는 Colab과 같은 대화형 Python Notebook을 실행할 수 있는 환경입니다.

  • OpenAI 모델을 사용하는 경우 OpenAI API 키가 있어야 합니다.

1

터미널 창에서 다음 명령을 실행하여 프로젝트를 초기화합니다.

dotnet new console -o MyCompany.Embeddings
cd MyCompany.Embeddings
2

터미널 창 에서 다음 명령을 실행 합니다.

dotnet add package MongoDB.Driver
3

환경 변수를 내보내고, PowerShell에서 set을 실행하거나 IDE의 환경 변수 관리자를 사용하여 연결 문자열과 HuggingFace 액세스 토큰을 프로젝트에서 사용할 수 있도록 합니다.

export HUGGINGFACE_ACCESS_TOKEN="<access-token>"
export ATLAS_CONNECTION_STRING="<connection-string>"

<access-token> 자리 표시자 값을 허깅 페이스 액세스 토큰으로 바꿉니다.

자리 <connection-string> 표시자 값을 Atlas cluster 의 SRV 연결 문자열 로 바꿉니다.

연결 문자열은 다음 형식을 사용해야 합니다.

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
4

AIService.cs라는 같은 이름의 파일에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 주어진 문자열 입력 배열에 대한 임베딩 배열을 생성하기 위해 GetEmbeddingsAsync라는 비동기 작업을 정의합니다. 이 함수는 mxbai-embed-large-v1 임베딩 모델을 사용합니다.

AIService.cs
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 오류가 발생할 수 있습니다. 이 문제를 해결하려면 잠시 후 다시 시도하세요.

1

터미널 창에서 다음 명령을 실행하여 프로젝트를 초기화합니다.

dotnet new console -o MyCompany.Embeddings
cd MyCompany.Embeddings
2

터미널 창 에서 다음 명령을 실행 합니다.

dotnet add package MongoDB.Driver
dotnet add package OpenAI
3

환경 변수를 내보내고, PowerShell에서 set을 실행하거나, IDE의 환경 변수 관리자를 사용하여 연결 문자열과 HuggingFace 액세스 토큰을 프로젝트에서 사용할 수 있도록 합니다.

export OPENAI_API_KEY="<api-key>"
export ATLAS_CONNECTION_STRING="<connection-string>"

<api-key> 자리 표시자 값을 OpenAI API 키로 바꿉니다.

자리 <connection-string> 표시자 값을 Atlas cluster 의 SRV 연결 문자열 로 바꿉니다.

연결 문자열은 다음 형식을 사용해야 합니다.

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
4

AIService.cs라는 같은 이름의 파일에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 주어진 문자열 입력 배열에 대한 임베딩 배열을 생성하기 위해 GetEmbeddingsAsync라는 비동기 작업을 정의합니다. 이 함수는 OpenAI의 text-embedding-3-small 모델을 사용하여 주어진 입력에 대한 임베딩을 생성합니다.

AIService.cs
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 키가 필요합니다.

1

터미널 창에서 다음 명령을 실행하여 my-embeddings-project라는 이름의 새 디렉토리를 만들고 프로젝트를 초기화합니다.

mkdir my-embeddings-project
cd my-embeddings-project
go mod init my-embeddings-project
2

터미널 창 에서 다음 명령을 실행 합니다.

go get github.com/joho/godotenv
go get go.mongodb.org/mongo-driver/v2/mongo
go get github.com/tmc/langchaingo/llms
3

프로젝트에서 Atlas 연결 문자열과 Hugging Face 액세스 토큰을 저장할 .env 파일을 생성하세요.

HUGGINGFACEHUB_API_TOKEN = "<access-token>"
ATLAS_CONNECTION_STRING = "<connection-string>"

<access-token> 자리 표시자 값을 허깅 페이스 액세스 토큰으로 바꿉니다.

자리 <connection-string> 표시자 값을 Atlas cluster 의 SRV 연결 문자열 로 바꿉니다.

연결 문자열은 다음 형식을 사용해야 합니다.

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
4
  1. 프로젝트에 common 디렉토리를 만들어 이후 단계에서 사용할 일반 코드를 저장합니다.

    mkdir common && cd common
  2. get-embeddings.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 주어진 입력에 대한 임베딩을 생성하는 GetEmbeddings 함수를 정의합니다. 이 기능은 다음을 지정합니다.

    get-embeddings.go
    package 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 오류가 발생할 수 있습니다. 이 문제를 해결하려면 잠시 후 다시 시도하세요.

  3. 메인 프로젝트 루트 디렉토리로 다시 이동합니다.

    cd ../
1

터미널 창에서 다음 명령을 실행하여 my-embeddings-project라는 이름의 새 디렉토리를 만들고 프로젝트를 초기화합니다.

mkdir my-embeddings-project
cd my-embeddings-project
go mod init my-embeddings-project
2

터미널 창 에서 다음 명령을 실행 합니다.

go get github.com/joho/godotenv
go get go.mongodb.org/mongo-driver/v2/mongo
go get github.com/milosgajdos/go-embeddings/openai
3

.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
4
  1. 프로젝트 에 common 라는 디렉토리 를 만들어 여러 단계에서 사용할 코드를 저장 합니다.

    mkdir common && cd common
  2. get-embeddings.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 OpenAI의 text-embedding-3-small 모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는 GetEmbeddings 함수를 정의합니다.

    get-embeddings.go
    package 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
    }
  3. 메인 프로젝트 루트 디렉토리로 다시 이동합니다.

    cd ../

이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI와 같은 독점 모델을 사용할지에 따라 탭을 선택하세요.

참고

오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.

1
  1. IDE에서 Maven 또는 Gradle을 사용하여 Java 프로젝트 만듭니다.

  2. 패키지 관리자에 따라 다음 종속성을 추가합니다.

    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.gradle
    dependencies {
    // 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'
    }
  3. 패키지 관리자를 실행하여 프로젝트 에 종속성을 설치합니다.

2

참고

이 예시 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>`` 자리 표시자 값을 Hugging Face 액세스 토큰으로 교체합니다.

  • 자리 <connection-string> 표시자 값을 Atlas cluster 의 SRV 연결 문자열 로 바꿉니다.

    연결 문자열은 다음 형식을 사용해야 합니다.

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
3

EmbeddingProvider.java 이라는 파일을 만들고 다음 코드를 붙여넣습니다.

이 코드는 mxbai-embed-large-v1 오픈 소스 임베딩 모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는 두 가지 메서드를 정의합니다.

  • 다중 입력 :getEmbeddings 메서드는 텍스트 입력 배열List<String>()을 허용하므로 한 번의 API 호출로 여러 임베딩을 만들 수 있습니다. 이 메서드는 Atlas cluster 에 저장하기 위해 API 에서 제공하는 float 배열을 double 의 BSON 배열로 변환합니다.

  • 단일 입력: 메서드는 getEmbedding String벡터 데이터에 대해 수행하려는 쿼리 나타내는 단일 를 허용합니다. 이 메서드는 컬렉션 을 쿼리할 때 사용할 수 있도록 API 에서 제공하는 부동 소수점 배열 을 double의 BSON 배열 로 변환합니다.

EmbeddingProvider.java
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());
}
}
1
  1. IDE에서 Maven 또는 Gradle을 사용하여 Java 프로젝트 만듭니다.

  2. 패키지 관리자에 따라 다음 종속성을 추가합니다.

    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.gradle
    dependencies {
    // 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'
    }
  3. 패키지 관리자를 실행하여 프로젝트 에 종속성을 설치합니다.

2

참고

이 예시 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 cluster 의 SRV 연결 문자열 로 바꿉니다.

    연결 문자열은 다음 형식을 사용해야 합니다.

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
3

EmbeddingProvider.java 이라는 파일을 만들고 다음 코드를 붙여넣습니다.

이 코드는 text-embedding- -small3 OpenAI 임베딩 모델을 사용하여 주어진 입력에 대한 임베딩을 생성하는 두 가지 메서드를 정의합니다.

  • 다중 입력 :getEmbeddings 메서드는 텍스트 입력 배열List<String>()을 허용하므로 한 번의 API 호출로 여러 임베딩을 만들 수 있습니다. 이 메서드는 Atlas cluster 에 저장하기 위해 API 에서 제공하는 float 배열을 double 의 BSON 배열로 변환합니다.

  • 단일 입력: 메서드는 getEmbedding String벡터 데이터에 대해 수행하려는 쿼리 나타내는 단일 를 허용합니다. 이 메서드는 컬렉션 을 쿼리할 때 사용할 수 있도록 API 에서 제공하는 부동 소수점 배열 을 double의 BSON 배열 로 변환합니다.

EmbeddingProvider.java
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 키가 필요합니다.

1

터미널 창에서 다음 명령을 실행하여 my-embeddings-project라는 이름의 새 디렉토리를 만들고 프로젝트를 초기화합니다.

mkdir my-embeddings-project
cd my-embeddings-project
npm init -y
2

ES 모듈을 사용하도록 프로젝트를 설정하려면 package.json 파일에 "type": "module"을 추가한 후 저장합니다.

{
"type": "module",
// other fields...
}
3

터미널 창에서 다음 명령을 실행합니다.

npm install mongodb @xenova/transformers
4
  1. 프로젝트에서 Atlas 연결 문자열을 저장할 .env 파일을 생성하세요.

    ATLAS_CONNECTION_STRING="<connection-string>"
  2. <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 패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.

  3. 파일을 저장합니다.

5
  1. get-embeddings.js이라는 파일을 만듭니다.

    touch get-embeddings.js
  2. 파일 에 다음 코드를 붙여넣습니다.

    이 코드는 지정된 입력에 대한 임베딩을 생성하는 getEmbedding 라는 함수를 정의합니다. 이 함수는 다음을 지정합니다.

    get-embeddings.js
    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);
    }
  3. 파일을 저장합니다.

1

터미널 창에서 다음 명령을 실행하여 my-embeddings-project라는 이름의 새 디렉토리를 만들고 프로젝트를 초기화합니다.

mkdir my-embeddings-project
cd my-embeddings-project
npm init -y
2

ES 모듈을 사용하도록 프로젝트를 설정하려면 package.json 파일에 "type": "module"을 추가한 후 저장합니다.

{
"type": "module",
// other fields...
}
3

터미널 창에서 다음 명령을 실행합니다.

npm install mongodb openai
4
  1. 프로젝트에서 .env 파일을 생성하여 Atlas 연결 문자열과 OpenAI API 키를 저장합니다.

    OPENAI_API_KEY = "<api-key>"
    ATLAS_CONNECTION_STRING = "<connection-string>"
  2. <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 패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.

  3. 파일을 저장합니다.

5
  1. get-embeddings.js이라는 파일을 만듭니다.

  2. 다음 코드를 붙여넣습니다. 이 코드는 OpenAI의 text-embedding-3-small 모델을 사용하여 지정된 입력에 대한 임베딩을 생성하는 getEmbedding 함수를 정의합니다.

    get-embeddings.js
    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;
    }
  3. 파일을 저장합니다.

이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 OpenAI의 독점 모델을 사용할지에 따라 탭을 선택하세요.

이 섹션에는 효율적인 저장 과 쿼리 성능 향상을 위해 임베딩을 압축하는 데 사용할 수 있는 선택적 함수도 포함되어 있습니다. 자세한 학습 은 벡터 압축을 참조하세요.

참고

오픈 소스 임베딩 모델은 무료로 사용할 수 있으며 애플리케이션에서 로컬로 로드할 수 있습니다. 독점적인 모델에서는 모델에 액세스하려면 API 키가 필요합니다.

1

.ipynb 확장자를 가진 파일을 저장하여 대화형 Python 노트북을 만든 다음 노트북에서 다음 명령을 실행하여 종속성을 설치합니다.

pip install --quiet --upgrade sentence-transformers pymongo einops
2

Nomic AI의 오픈 소스 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 생성하려면 다음 코드를 노트북에 붙여넣고 실행하세요. . 이 코드는 다음을 수행합니다.

  • nomic-embed-text-v1 임베딩 모델을 로드합니다.

  • 모델을 사용하여 지정된 텍스트 입력에 대한 임베딩을 생성하는 get_embedding 라는 함수를 만듭니다. 기본값 정밀도는 float32입니다.

  • 문자열 foo에 대한 임베딩을 생성합니다.

from sentence_transformers import SentenceTransformer
# Load the embedding model
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
# Define a function to generate embeddings
def get_embedding(data, precision="float32"):
return model.encode(data, precision=precision).tolist()
# Generate an embedding
embedding = get_embedding("foo")
print(embedding)
[-0.02980827 0.03841474 -0.02561123 ... -0.0532876 -0.0335409 -0.02591543]
1

.ipynb 확장자를 가진 파일을 저장하여 대화형 Python 노트북을 만든 다음 노트북에서 다음 명령을 실행하여 종속성을 설치합니다.

pip install --quiet --upgrade openai pymongo
2

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
embedding = get_embedding("foo")
print(embedding)
[-0.005843308754265308, -0.013111298903822899, -0.014585349708795547, 0.03580040484666824, 0.02671629749238491, ... ]

다음도 참조하세요.

API 정보와 사용 가능한 모델 목록은 OpenAI 문서를 참조하세요.

이 섹션에서는 정의한 함수를 사용하여 데이터에서 벡터 임베딩을 만든 다음 이러한 임베딩을 Atlas 의 컬렉션 에 저장 .

새 데이터에서 임베딩을 만들 것인지, 아니면 Atlas에 이미 있는 기존 데이터에서 임베딩을 만들 것인지에 따라 탭을 선택합니다.

1

DataService.cs라는 같은 이름의 파일에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 AddDocumentsAsync라는 이름의 비동기 작업을 정의하여 Atlas에 문서를 추가합니다. 이 함수는 Collection.InsertManyAsync() C# 드라이버 메서드를 사용하여 BsonDocument 유형의 목록을 삽입합니다. 각 문서에는 다음이 포함됩니다.

  • 영화 요약이 포함된 text 필드.

  • 벡터 임베딩을 생성하여 얻은 부동 소수점 배열이 포함된 embedding 필드.

DataService.cs
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();
}
}
2

다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.

구체적으로, 이 코드는 사용자가 정의한 GetEmbeddingsAsync 함수를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 Atlas의 sample_db.embeddings 컬렉션에 수집합니다.

Program.cs
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);
3
dotnet run MyCompany.Embeddings.csproj
Successfully inserted 3 documents into Atlas

클러스터의 sample_db.embeddings 컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.

참고

이번 예시에서는 샘플 데이터sample_airbnb.listingsAndReviews 컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.

1

DataService.cs라는 같은 이름의 파일에 새 클래스를 만들고 다음 코드를 붙여넣습니다. 이 코드는 다음 작업을 수행하는 함수 두 개를 생성합니다.

  • Atlas cluster에 연결합니다.

  • GetDocuments 메서드는 sample_airbnb.listingsAndReviews 컬렉션에서 summary 필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.

  • AddEmbeddings 비동기 작업은 _idGetDocuments 메서드에서 조회된 문서 중 하나와 일치하는 sample_airbnb.listingsAndReviews 컬렉션의 문서에 새 embeddings 필드를 생성합니다.

DataService.cs
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;
}
}
2

다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.

구체적으로, 이 코드는 사용자가 정의한 GetEmbeddingsAsync 함수를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 Atlas의 sample_db.embeddings 컬렉션에 수집합니다.

Program.cs
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");
}
3
dotnet run MyCompany.Embeddings.csproj
Generating embeddings.
50 documents updated successfully.
1

다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다.

구체적으로, 이 코드는 사용자가 정의한 GetEmbeddings 함수와 MongoDB Go 드라이버를 사용하여 샘플 텍스트 배열에서 임베딩을 생성하고 이를 Atlas에서 sample_db.embeddings 컬렉션으로 수집합니다.

create-embeddings.go
package main
import (
"context"
"fmt"
"log"
"my-embeddings-project/common"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/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(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))
}
create-embeddings.go
package main
import (
"context"
"fmt"
"log"
"my-embeddings-project/common"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/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(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))
}
2
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 컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.

1

다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다. 구체적으로 이 코드는 다음을 수행합니다.

  • Atlas 클러스터에 연결합니다.

  • sample_airbnb.listingsAndReviews 컬렉션에서 summary 필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.

  • 정의한 GetEmbeddings 함수를 사용하여 각 문서의 summary 필드에서 임베딩을 생성합니다.

  • MongoDB Go 드라이버를 사용하여 임베딩 값이 포함된 새 embeddings 필드로 각 문서를 업데이트합니다.

create-embeddings.go
package main
import (
"context"
"log"
"my-embeddings-project/common"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/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(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)
}
2

BSON 과의 고 (Go) 객체 마셜링 및 언마셜링을 간소화하려면 이 컬렉션 의 문서에 대한 모델이 포함된 파일 을 만듭니다.

  1. common 디렉토리 로 이동합니다.

    cd common
  2. models.go 이라는 파일 을 만들고 다음 코드를 붙여넣습니다.

    models.go
    package common
    import (
    "time"
    "go.mongodb.org/mongo-driver/v2/bson"
    )
    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 bson.Decimal128 `bson:"bathrooms"`
    Amenities []string `bson:"amenities"`
    Price bson.Decimal128 `bson:"price"`
    WeeklyPrice bson.Decimal128 `bson:"weekly_price"`
    MonthlyPrice bson.Decimal128 `bson:"monthly_price"`
    CleaningFee bson.Decimal128 `bson:"cleaning_fee"`
    ExtraPeople bson.Decimal128 `bson:"extra_people"`
    GuestsIncluded bson.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.go
    package common
    import (
    "time"
    "go.mongodb.org/mongo-driver/v2/bson"
    )
    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 bson.Decimal128 `bson:"bathrooms"`
    Amenities []string `bson:"amenities"`
    Price bson.Decimal128 `bson:"price"`
    WeeklyPrice bson.Decimal128 `bson:"weekly_price"`
    MonthlyPrice bson.Decimal128 `bson:"monthly_price"`
    CleaningFee bson.Decimal128 `bson:"cleaning_fee"`
    ExtraPeople bson.Decimal128 `bson:"extra_people"`
    GuestsIncluded bson.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"`
    }
  3. 프로젝트 루트 디렉토리 로 다시 이동합니다.

    cd ../
3
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

클러스터의 sample_airbnb.listingsAndReviews 컬렉션으로 이동하고 문서의 필드를 확장하여 Atlas UI에서 벡터 임베딩을 볼 수 있습니다.

1

CreateEmbeddings.java 이라는 파일을 만들고 다음 코드를 붙여넣습니다.

이 코드는 getEmbeddings 메서드와 MongoDB Java 동기화 드라이버 사용하여 다음을 수행합니다.

  1. Atlas cluster에 연결합니다.

  2. 샘플 텍스트의 배열 가져옵니다.

  3. 이전에 정의한 getEmbeddings 메서드를 사용하여 각 텍스트에서 임베딩을 생성합니다.

  4. Atlas 의 sample_db.embeddings 컬렉션 에 임베딩을 수집합니다.

CreateEmbeddings.java
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);
}
}
}
2

파일 저장하고 실행 . 출력은 다음과 유사합니다.

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 컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.

1

CreateEmbeddings.java 이라는 파일을 만들고 다음 코드를 붙여넣습니다.

이 코드는 getEmbeddings 메서드와 MongoDB Java 동기화 드라이버 사용하여 다음을 수행합니다.

  1. Atlas cluster에 연결합니다.

  2. 비어 있지 않은 summary 필드 있는 sample_airbnb.listingsAndReviews 컬렉션 에서 문서의 하위 집합을 가져옵니다.

  3. 이전에 정의한 getEmbeddings 메서드를 사용하여 각 문서의 summary 필드 에서 임베딩을 생성합니다.

  4. 임베딩 값이 포함된 새 embeddings 필드 로 각 문서 업데이트합니다.

CreateEmbeddings.java
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);
}
}
}
2

파일 저장하고 실행 . 출력은 다음과 유사합니다.

Generating embeddings for 50 documents.
This operation may take up to several minutes.
Added embeddings successfully to 50 documents.

클러스터의 sample_airbnb.listingsAndReviews 컬렉션으로 이동하여 Atlas UI에서 벡터 임베딩을 볼 수도 있습니다.

1

다음 코드를 사용하여 Atlas 의 기존 컬렉션 에서 임베딩을 생성합니다. 이 코드는 사용자가 정의한 getEmbedding 함수와 Node.js 드라이버 사용하여 샘플 텍스트 배열 에서 임베딩을 생성하고 sample_db.embeddings Atlas 의 컬렉션 으로 수집합니다.

convertEmbeddingsToBSON 함수를 정의한 경우 332~33 줄의 주석 처리를 제거하여 임베딩을 BSON binData 벡터로 변환합니다.

create-embeddings.js
import { MongoClient } from 'mongodb';
import { getEmbedding } from './get-embeddings.js';
// import { convertEmbeddingsToBSON } from './convert-embeddings.js';
// Data to embed
const texts = [
"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");
console.log("Generating embeddings and inserting documents...");
const insertDocuments = [];
await Promise.all(texts.map(async text => {
// Check if the document already exists
const existingDoc = await collection.findOne({ text: text });
// Generate an embedding using the function that you defined
var embedding = await getEmbedding(text);
// Uncomment the following lines to convert the generated embedding into BSON format
// const bsonEmbedding = await convertEmbeddingsToBSON([embedding]); // Since convertEmbeddingsToBSON is designed to handle arrays
// embedding = bsonEmbedding; // Use BSON embedding instead of the original float32 embedding
// Add the document with the embedding to array of documents for bulk insert
if (!existingDoc) {
insertDocuments.push({
text: text,
embedding: embedding
})
}
}));
// Continue processing documents if an error occurs during an operation
const options = { ordered: false };
// Insert documents with embeddings into Atlas
const result = await collection.insertMany(insertDocuments, options);
console.log("Count of documents inserted: " + result.insertedCount);
} catch (err) {
console.log(err.stack);
}
finally {
await client.close();
}
}
run().catch(console.dir);
2
node --env-file=.env create-embeddings.js
Generating embeddings and inserting documents...
Count of documents inserted: 3

클러스터의 sample_db.embeddings 컬렉션으로 이동하여 Atlas UI 에서 벡터 임베딩을 볼 수 있습니다.

참고

이번 예시에서는 샘플 데이터sample_airbnb.listingsAndReviews 컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.

1

다음 코드를 사용하여 Atlas의 기존 컬렉션에서 임베딩을 생성합니다. 구체적으로 이 코드는 다음을 수행합니다.

  • Atlas 클러스터에 연결합니다.

  • sample_airbnb.listingsAndReviews 컬렉션에서 summary 필드가 비어 있지 않은 문서의 하위 집합을 가져옵니다.

  • 정의한 getEmbedding 함수를 사용하여 각 문서의 summary 필드에서 임베딩을 생성합니다.

  • MongoDB Node.js 드라이버를 사용하여 임베딩 값이 포함된 새 embedding 필드로 각 문서를 업데이트합니다.

convertEmbeddingsToBSON 함수를 정의한 경우 329~30 줄의 주석 처리를 제거하여 임베딩을 BSON binData 벡터로 변환합니다.

create-embeddings.js
import { MongoClient } from 'mongodb';
import { getEmbedding } from './get-embeddings.js';
// import { convertEmbeddingsToBSON } from './convert-embeddings.js';
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_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();
console.log("Generating embeddings and updating documents...");
const updateDocuments = [];
await Promise.all(documents.map(async doc => {
// Generate an embedding using the function that you defined
var embedding = await getEmbedding(doc.summary);
// Uncomment the following lines to convert the generated embedding into BSON format
// const bsonEmbedding = await convertEmbeddingsToBSON([embedding]); // Since convertEmbeddingsToBSON is designed to handle arrays
// embedding = bsonEmbedding; // Use BSON embedding instead of the original float32 embedding
// Add the embedding to an array of update operations
updateDocuments.push(
{
updateOne: {
filter: { "_id": doc._id },
update: { $set: { "embedding": embedding } }
}
}
)
}));
// Continue processing documents if an error occurs during an operation
const options = { ordered: false };
// Update documents with the new embedding field
const result = await collection.bulkWrite(updateDocuments, options);
console.log("Count of documents updated: " + result.modifiedCount);
} catch (err) {
console.log(err.stack);
}
finally {
await client.close();
}
}
run().catch(console.dir);
2
node --env-file=.env create-embeddings.js
Generating embeddings and updating documents...
Count of documents updated: 50

클러스터의 sample_airbnb.listingsAndReviews 컬렉션으로 이동하고 문서의 필드를 확장하여 Atlas UI에서 벡터 임베딩을 볼 수 있습니다.

1

다음 코드는 샘플 텍스트 배열 정의합니다.

# Sample data
texts = [
"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"
]
2

get_embedding 함수를 사용하여 데이터에서 임베딩을 생성합니다. 다음 코드를 사용하여 샘플 텍스트에서 임베딩을 생성합니다.

generate_bson_vector 함수를 정의한 경우 이 함수를 호출하는 줄의 주석을 제거하여 임베딩을 binData 벡터로 압축합니다. 임베딩은 바이너리 형식으로 표시됩니다.

# Generate embeddings from the sample data
embeddings = []
for text in texts:
embedding = get_embedding(text)
# Uncomment the following line to convert to BSON
# embedding = generate_bson_vector(embedding, BinaryVectorDtype.FLOAT32)
embeddings.append(embedding)
# Print the embeddings
print(f"\nText: {text}")
print(f"Embedding: {embedding[:3]}... (truncated)")
Generated embeddings:
Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built
Embedding: [-0.01089042 0.05926645 -0.00291325]... (truncated)
Text: The Lion King: Lion cub and future king Simba searches for his identity
Embedding: [-0.05607051 -0.01360618 0.00523855]... (truncated)
Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission
Embedding: [-0.0275258 0.01144342 -0.02360895]... (truncated)
3

임베딩이 포함된 문서를 생성하고 Atlas cluster 로 수집하려면 다음 단계를 수행하세요.

  1. 문서를 생성하는 함수를 정의합니다.

    def create_docs_with_embeddings(embeddings, data):
    docs = []
    for i, (embedding, text) in enumerate(zip(embeddings, data)):
    doc = {
    "_id": i,
    "text": text,
    "embedding": embedding,
    }
    docs.append(doc)
    return docs
  2. 임베딩을 사용하여 문서를 만듭니다.

    # Create documents with embeddings and sample data
    docs = create_docs_with_embeddings(embeddings, texts)
  3. 문서를 Atlas에 삽입합니다.

    노트북에 다음 코드를 붙여넣고 실행 <connection-string> 을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.

    참고

    연결 문자열은 다음 형식을 사용해야 합니다.

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

    이 코드는 다음을 수행합니다.

    • Atlas 클러스터에 연결합니다.

    • 지정된 데이터베이스 및 컬렉션 에 문서를 삽입합니다.

    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], acknowledged=True)

    클러스터의 sample_db.embeddings 네임스페이스에 대한 Atlas UI 에서 벡터 임베딩을 확인하여 확인할 수 있습니다.

참고

이번 예시에서는 샘플 데이터sample_airbnb.listingsAndReviews 컬렉션을 사용하지만, 클러스터의 모든 컬렉션에서 작동하도록 코드를 조정할 수 있습니다.

1

Atlas cluster 에서 데이터를 로드합니다. 다음 코드는 sample_airbnb.listingAndReviews 컬렉션 에서 50 문서의 하위 집합을 가져옵니다.

<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_airbnb"]
collection = db["listingsAndReviews"]
# Define a filter to exclude documents with null or empty 'summary' fields
filter = { 'summary': { '$exists': True, "$nin": [ None, "" ] } }
# Get a subset of documents in the collection
documents = collection.find(filter, {'_id': 1, 'summary': 1}).limit(50)
2

이전 단계에서 로드한 문서에서 임베딩을 생성합니다. 이 코드는 다음을 수행합니다.

  • 정의한 get_embedding 함수를 사용하여 각 문서의 summary 필드에서 임베딩을 생성합니다.

  • 임베딩 값이 포함된 새 embedding 필드 로 각 문서 업데이트합니다.

벡터 임베딩을 BSON binData 벡터로 변환하는 generate_bson_vector 함수를 정의한 경우 코드를 실행 전에 이 함수를 호출하는 줄의 주석 처리를 제거합니다.

참고

이 작업은 완료하는 데 몇 분 정도 걸릴 수 있습니다.

from pymongo import UpdateOne
# Generate the list of bulk write operations
operations = []
for doc in documents:
summary = doc["summary"]
# Generate embeddings for this document
embedding = get_embedding(summary)
# Uncomment the following line to convert to BSON vectors
# embedding = generate_bson_vector(embedding, BinaryVectorDtype.FLOAT32)
# Add the update operation to the list
operations.append(UpdateOne(
{"_id": doc["_id"]},
{"$set": {
"embedding": embedding
}}
))
# Execute the bulk write operation
if operations:
result = collection.bulk_write(operations)
updated_doc_count = result.modified_count
print(f"Updated {updated_doc_count} documents.")
Updated 50 documents.

이 섹션에서는 컬렉션의 벡터 임베딩을 인덱싱하고 샘플 벡터 검색 쿼리를 실행하는 데 사용하는 임베딩을 만듭니다.

쿼리를 실행하면 Atlas Vector Search는 벡터 검색 쿼리에서 임베딩과 거리가 가장 가까운 임베딩을 가진 문서를 반환합니다. 이는 의미상 유사함을 나타냅니다.

1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct으로 지정하는 sample_db.embeddings 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. 다음 코드를 붙여넣어 DataService.csDataService 클래스에 CreateVectorIndex 함수를 추가합니다.

    DataService.cs
    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)
    {
    // 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}");
    }
    }
    }
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 1024(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. Program.cs의 코드를 업데이트합니다.

    초기 문서를 채우는 코드를 제거하고, 인덱스를 생성하기 위해 다음 코드로 대체합니다.

    Program.cs
    using MyCompany.Embeddings;
    var dataService = new DataService();
    dataService.CreateVectorIndex();
  4. 파일을 저장한 후, 프로젝트를 컴파일하고 실행하여 인덱스를 만듭니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. 다음 코드를 붙여넣어 DataService.csDataService 클래스에 PerformVectorQuery 함수를 추가합니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    DataService.cs
    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)
    {
    // 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();
    }
    }
  2. Program.cs의 코드를 업데이트합니다.

    벡터 인덱스를 생성한 코드를 제거하고, 쿼리를 수행하는 코드를 추가합니다.

    Program.cs
    using 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());
    }
    }
    }
  3. 파일을 저장한 후, 프로젝트를 컴파일하고 실행하여 쿼리를 수행합니다.

    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 }
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embeddings 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 sample_airbnb.listingsAndReviews 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. DataService.cs에서 DataService 클래스에 CreateVectorIndex 함수를 추가하기 위해 다음 코드를 붙여넣습니다.

    DataService.cs
    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()
    {
    // 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}");
    }
    }
    }
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 1024(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. Program.cs의 코드를 업데이트합니다.

    기존 문서에 임베딩을 추가한 코드를 제거하고, 인덱스를 생성하기 위해 다음 코드로 대체합니다.

    Program.cs
    using MyCompany.Embeddings;
    var dataService = new DataService();
    dataService.CreateVectorIndex();
  4. 파일을 저장한 후, 프로젝트를 컴파일하고 실행하여 인덱스를 만듭니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. 다음 코드를 붙여넣어 DataService.csDataService 클래스에 PerformVectorQuery 함수를 추가합니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    DataService.cs
    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()
    {
    // 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();
    }
    }
  2. Program.cs의 코드를 업데이트합니다.

    벡터 인덱스를 생성한 코드를 제거하고, 쿼리를 수행하는 코드를 추가합니다.

    Program.cs
    using 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());
    }
    }
    }
  3. 파일을 저장한 후, 프로젝트를 컴파일하고 실행하여 쿼리를 수행합니다.

    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 }
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct으로 지정하는 sample_db.embeddings 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. create-index.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    create-index.go
    package main
    import (
    "context"
    "fmt"
    "log"
    "os"
    "time"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/v2/bson"
    "go.mongodb.org/mongo-driver/v2/mongo"
    "go.mongodb.org/mongo-driver/v2/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(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)
    }
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 1024(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. 파일을 저장하고 다음 명령을 실행 합니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. vector-query.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    vector-query.go
    package main
    import (
    "context"
    "fmt"
    "log"
    "my-embeddings-project/common"
    "os"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/v2/bson"
    "go.mongodb.org/mongo-driver/v2/mongo"
    "go.mongodb.org/mongo-driver/v2/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(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.go
    package main
    import (
    "context"
    "fmt"
    "log"
    "my-embeddings-project/common"
    "os"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/v2/bson"
    "go.mongodb.org/mongo-driver/v2/mongo"
    "go.mongodb.org/mongo-driver/v2/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(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)
    }
    }
  2. 파일을 저장하고 다음 명령을 실행 합니다.

    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
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embeddings 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 sample_airbnb.listingsAndReviews 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. create-index.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    create-index.go
    package 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"}},
    },
    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)
    }
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 1024(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. 파일을 저장하고 다음 명령을 실행 합니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. vector-query.go라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    vector-query.go
    package 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.go
    package 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)
    }
    }
  2. 파일을 저장하고 다음 명령을 실행 합니다.

    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
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct으로 지정하는 sample_db.embeddings 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. CreateIndex.java 이라는 파일 만들고 다음 코드를 붙여넣습니다.

    CreateIndex.java
    import 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);
    }
    }
    }
  2. <dimensions> 자리 표시자 값을 사용한 모델에 적합한 변수로 바꿉니다.

    • dimensionsHuggingFaceModel: 1024 차원("mixedbread-ai/mxbai-embed-large-v1" 모델)

    • dimensionsOpenAiModel: 1536 차원("text-embedding-3-small" 모델)

    참고

    차원 수는 임베딩을 생성하는 데 사용된 모델에 따라 결정됩니다. 다른 모델을 사용하도록 이 코드를 수정하는 경우 numDimensions에 올바른 값을 전달해야 합니다. 임베딩 모델 선택 섹션도 참조하세요.

  3. 파일 저장하고 실행 . 출력은 다음과 유사합니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. VectorQuery.java라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    VectorQuery.java
    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.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);
    }
    }
    }
  2. 파일 저장하고 실행 . 출력은 사용한 모델에 따라 다음 중 하나와 유사합니다.

    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
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embeddings 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 sample_airbnb.listingsAndReviews 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. CreateIndex.java 이라는 파일 만들고 다음 코드를 붙여넣습니다.

    CreateIndex.java
    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.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")));
    // 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);
    }
    }
    }
  2. <dimensions> 자리 표시자 값을 사용한 모델에 적합한 변수로 바꿉니다.

    • dimensionsHuggingFaceModel: 1024 차원(오픈 소스)

    • dimensionsOpenAiModel: 1536 차원

    참고

    차원 수는 임베딩을 생성하는 데 사용된 모델에 따라 결정됩니다. 다른 모델을 사용하는 경우 numDimensions에 올바른 값을 전달해야 합니다. 임베딩 모델 선택 섹션도 참조하세요.

  3. 파일 저장하고 실행 . 출력은 다음과 유사합니다.

    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 인덱스 생성하기를 참조하세요.

2
  1. VectorQuery.java라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    VectorQuery.java
    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.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);
    }
    }
    }
  2. 파일 저장하고 실행 . 출력은 사용한 모델에 따라 다음 중 하나와 유사합니다.

    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
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 dotProduct으로 지정하는 sample_db.embeddings 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. create-index.js라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    create-index.js
    import { 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);
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 768(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. 파일을 저장하고 다음 명령을 실행 합니다.

    node --env-file=.env create-index.js

참고

인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

2
  1. vector-query.js라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    vector-query.js
    import { 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);
  2. 파일을 저장하고 다음 명령을 실행 합니다.

    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.7007871866226196}
    {"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.6327334046363831}
    {"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.5544710159301758}
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 sample_airbnb.listingsAndReviews 컬렉션에 인덱스를 생성하려면 다음 단계를 완료하세요.

  1. create-index.js라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    create-index.js
    import { 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>
    }
    ]
    }
    }
    // Call the method to create the index
    const result = await collection.createSearchIndex(index);
    console.log(result);
    } finally {
    await client.close();
    }
    }
    run().catch(console.dir);
  2. 오픈 소스 모델을 사용한 경우 <dimensions> 자리 표시자 값을 768(으)로 바꾸고, OpenAI의 모델을 사용한 경우 1536(으)로 바꿉니다.

  3. 파일을 저장하고 다음 명령을 실행 합니다.

    node --env-file=.env create-index.js

참고

인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

2
  1. vector-query.js라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다.

    벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

    예를 들어 이 코드는 다음을 수행합니다.

    • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

    • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

    • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

    • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

    vector-query.js
    import { 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);
  2. 파일을 저장하고 다음 명령을 실행 합니다.

    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}
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

  1. 다음 코드를 노트북에 붙여넣습니다.

    이 코드는 컬렉션에 다음을 지정하는 인덱스를 생성합니다.

    • embedding 필드를 벡터 유형 필드로 지정합니다.

    • dotProduct float32 임베딩의 유사성 유형으로 사용됩니다.

    • 768 을 임베딩의 차원 수로 지정합니다.

    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": 768
    }
    ]
    },
    name="vector_index",
    type="vectorSearch"
    )
    collection.create_search_index(model=search_index_model)
  2. 코드를 실행합니다.

    인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

  1. 다음 코드를 노트북에 붙여넣습니다.

    이 코드는 컬렉션 에 인덱스 생성하고 필드 embedding 벡터 dotProduct유형으로, 유사성 함수를, 차원 수를 로 1536 지정합니다.

    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
    }
    ]
    },
    name="vector_index",
    type="vectorSearch"
    )
    collection.create_search_index(model=search_index_model)
  2. 코드를 실행합니다.

    인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

2

벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

예를 들어 이 코드는 다음을 수행합니다.

  • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

  • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

  • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

  • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

참고

쿼리를 완료하는 데 시간이 걸릴 수 있습니다.

# 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)
{'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.7661112546920776}
{'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.6877288222312927}
# 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.7007871866226196}
{"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.6327334046363831}
{"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.5544710159301758}
1

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

  1. 다음 코드를 노트북에 붙여넣습니다.

    이 코드는 컬렉션에 다음을 지정하는 인덱스를 생성합니다.

    • embedding 필드를 벡터 유형 필드로 지정합니다.

    • dotProduct float32 임베딩의 유사성 유형으로 사용됩니다.

    • 768 을 임베딩의 차원 수로 지정합니다.

    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": 768
    }
    ]
    },
    name="vector_index",
    type="vectorSearch"
    )
    collection.create_search_index(model=search_index_model)
  2. 코드를 실행합니다.

    인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

데이터에서 벡터 검색 쿼리를 사용하려면 컬렉션에 Atlas Vector Search 인덱스를 만들어야 합니다.

  1. 다음 코드를 노트북에 붙여넣습니다.

    이 코드는 컬렉션 에 인덱스 생성하고 필드 embedding 벡터 dotProduct유형으로, 유사성 함수를, 차원 수를 로 1536 지정합니다.

    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
    }
    ]
    },
    name="vector_index",
    type="vectorSearch"
    )
    collection.create_search_index(model=search_index_model)
  2. 코드를 실행합니다.

    인덱스 작성에는 약 1분 정도가 소요됩니다. 인덱스가 작성되는 동안 인덱스는 초기 동기화 상태에 있습니다. 빌드가 완료되면 컬렉션의 데이터 쿼리를 시작할 수 있습니다.

자세한 내용은 Atlas Vector Search 인덱스 생성하기를 참조하세요.

2

벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

예를 들어 이 코드는 다음을 수행합니다.

  • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

  • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

  • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

  • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

# 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': '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}

벡터 검색 쿼리를 실행하려면 집계 파이프라인에 전달할 쿼리 벡터를 생성하세요.

예를 들어 이 코드는 다음을 수행합니다.

  • 정의한 임베딩 함수를 사용하여 쿼리 임베딩을 생성합니다.

  • queryVector 필드 에 이 임베딩을 사용하고 쿼리 할 경로를 지정합니다.

  • $vectorSearch 를 사용하여 ENN 검색 수행합니다.

  • 의미적으로 유사한 문서를 검색 점수와 함께 관련성에 따라 순위를 매겨 반환합니다.

# 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에 대한 임베딩 모델을 선택할 때 다음 지표를 고려하세요.

  • 임베딩 차원: 벡터 임베딩의 길이입니다.

    임베딩 크기가 작을수록 저장 효율이 높고, 임베딩 크기가 클수록 데이터의 미묘한 관계를 더 잘 포착할 수 있습니다. 선택하는 모델은 효율성과 복잡성 사이의 균형을 유지해야 합니다.

  • Max Tokens: 단일 임베딩으로 압축할 수 있는 토큰의 수입니다.

  • 모델 크기: 모델의 크기(기가바이트)입니다.

    더 큰 모델은 성능이 뛰어나지만 Atlas Vector Search를 프로덕션으로 확장할 때 더 많은 컴퓨팅 자원이 필요합니다.

  • 조회 평균: 조회 시스템의 성능을 측정하는 점수입니다.

    점수가 높을수록 모델이 검색된 결과 목록에서 관련 문서의 순위를 더 높게 매기는 데 더 적합하다는 것을 나타냅니다. 이 점수는 RAG 애플리케이션에 대한 모델을 선택할 때 중요합니다.

부동 소수점 벡터가 많고 의 저장 및 WiredTiger 공간(예: 디스크 및 메모리 사용량)을 mongod 줄이려면 임베딩을 binData 벡터로 변환하여 압축하세요.

BinData 는 바이너리 데이터를 저장하는 BSON 데이터 유형 입니다. 벡터 임베딩의 기본값 유형은 32비트 부동 소수점(float32) 배열 입니다. 바이너리 데이터는 기본값 배열 형식보다 저장 효율적이므로 디스크 공간이 3배 적습니다.

binData 벡터를 저장하면 문서 작업 세트 에 로드하는 데 필요한 리소스가 줄어들기 때문에 쿼리 성능이 향상됩니다. 이렇게 하면 20 문서를 통해 반환하는 벡터 쿼리의 쿼리 속도가 크게 향상될 수 있습니다. float32 임베딩을 압축하는 경우 float32 또는 binData 벡터를 사용하여 쿼리 할 수 있습니다.

이 페이지의 튜토리얼에는 예시 함수 가 포함되어 있으며, 이를 사용하여 float32 벡터를 binData 벡터로 변환할 수 있습니다.

BSON BinData 벡터는 다음 드라이버에서 지원됩니다.

부동 소수점 벡터는 배열 의 각 요소가 고유한 유형을 가지고 있기 때문에 일반적으로 압축하기가 어렵습니다(대부분의 벡터 유형이 균일함에도 불구하고). 이러한 이유로 임베딩 모델의 float 벡터 출력을 하위 유형이 float32binData 벡터로 변환하는 것이 더 효율적인 직렬화 체계입니다. binData 벡터는 전체 벡터에 대한 단일 유형 설명자를 저장 저장 오버헤드 줄어듭니다.

임베딩이 올바르고 최적화된지 확인하려면 다음 전략을 고려하세요.

Atlas Vector Search로 임베딩을 만들고 임베딩을 쿼리하는 방법을 익혔다면, 검색 증강 생성(RAG)을 구현하여 생성형 인공지능 애플리케이션 빌드를 시작하세요.

또한 32비트 부동소수점 벡터 임베딩을 더 적은 비트로 양자화하여 리소스 소비를 더욱 줄이고 쿼리 속도를 개선할 수도 있습니다. 자세한 학습은 벡터 양자화를 참조하세요.

돌아가기

Atlas Vector Search 빠른 시작