Docs Menu
Docs Home
/
MongoDB Atlas
/

벡터 임베딩을 만드는 방법

이 페이지의 내용

  • 시작하기
  • 전제 조건
  • 임베딩 함수 정의하기
  • 데이터에서 임베딩 생성
  • 쿼리에 대한 임베딩 만들기
  • 고려 사항
  • 임베딩 생성 방법 선택
  • 임베딩 모델 선택
  • 임베딩 유효성 검사
  • 문제 해결
  • 다음 단계

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

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

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

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

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

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


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


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

  • MongoDB 버전 6.0.11, 7.0.2 또는 그 이상의 버전을 실행하는 Atlas 클러스터.

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

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

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

  • MongoDB 버전 6.0.11, 7.0.2 또는 그 이상의 버전을 실행하는 Atlas 클러스터.

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

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

이 섹션에서는 임베딩 모델을 사용하여 벡터 임베딩을 생성하는 함수를 정의합니다. 오픈 소스 임베딩 모델을 사용할지, 아니면 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/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> 자리 표시자 값을 Hugging Face 액세스 토큰과 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 이라는 파일 을 만들고 다음 코드를 붙여넣습니다. 이 코드는 지정된 입력에 대한 임베딩을 생성하는 GetEmbeddings 라는 함수를 정의합니다. 이 함수는 다음을 지정합니다.

    • LangChain의 고 (Go)feature-extraction 포트를 사용하는 작업 은 라이브러리.학습 내용은 작업 을 참조하세요. LangChain JavaScript 설명서의 설명서를 참조하세요.

    • mxbai-embed-large-v1 임베딩 모델.

    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

    허깅 페이스 모델 허브 모델을 호출할 때 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/mongo
go get github.com/milosgajdos/go-embeddings/openai
3

프로젝트 에서 연결 문자열 과 OpenAI API 토큰을 저장 .env 파일 을 만듭니다.

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

<api-key><connection-string> 자리 표시자 값을 Atlas cluster 의 OpenAI API 키 및 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 ../
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

프로젝트에서 Atlas 연결 문자열을 저장할 .env 파일을 생성하세요.

ATLAS_CONNECTION_STRING = "<connection-string>"

<connection-string> 자리 표시자 값을 Atlas cluster 의 SRV 연결 문자열 로 바꿉니다. 연결 문자열 은 다음 형식을 사용해야 합니다.

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

참고

최소 Node.js 버전 요구 사항

Node.js v20.x --env-file 옵션을 도입했습니다. 이전 버전의 Node.js를 사용하는 경우 프로젝트에 dotenv 패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.

5

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

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);
}
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

프로젝트 에서 .env 파일 을 만들어 Atlas 연결 문자열 과 OpenAI API 키를 저장 합니다.

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

<api-key><connection-string> 자리 표시자 값을 Atlas cluster 의 OpenAI API 키 및 SRV 연결 문자열 로 바꿉니다. 연결 문자열 은 다음 형식을 사용해야 합니다.

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

참고

최소 Node.js 버전 요구 사항

Node.js v20.x --env-file 옵션을 도입했습니다. 이전 버전의 Node.js를 사용하는 경우 프로젝트에 dotenv 패키지를 추가하거나 다른 방법으로 환경 변수를 관리하세요.

5

get-embeddings.js라는 이름의 파일을 만들고 다음 코드를 붙여넣습니다. 이 코드는 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;
}
1

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

pip install --quiet sentence-transformers pymongo einops
2

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

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

  • 주어진 텍스트 입력에 대한 임베딩을 생성하기 위해 모델을 사용하는 get_embedding이라는 함수를 생성합니다.

  • 문자열 foo에 대한 단일 임베딩을 생성하여 함수를 테스트합니다.

from sentence_transformers import SentenceTransformer
# Load the embedding model (https://huggingface.co/nomic-ai/nomic-embed-text-v1")
model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
# Define a function to generate embeddings
def get_embedding(data):
"""Generates vector embeddings for the given data."""
embedding = model.encode(data)
return embedding.tolist()
# Generate an embedding
get_embedding("foo")
[-0.029808253049850464, 0.03841473162174225, -0.02561120130121708, -0.06707508116960526, 0.03867151960730553, ... ]
1

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

pip install --quiet 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
get_embedding("foo")
[-0.005843308754265308, -0.013111298903822899, -0.014585349708795547, 0.03580040484666824, 0.02671629749238491, ... ]

다음도 참조하세요.

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

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

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

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/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var data = []string{
"Titanic: The story of the 1912 sinking of the largest luxury liner ever built",
"The Lion King: Lion cub and future king Simba searches for his identity",
"Avatar: A marine is dispatched to the moon Pandora on a unique mission",
}
type TextWithEmbedding struct {
Text string
Embedding []float32
}
func main() {
ctx := context.Background()
if err := godotenv.Load(); err != nil {
log.Println("no .env file found")
}
// Connect to your Atlas cluster
uri := os.Getenv("ATLAS_CONNECTION_STRING")
if uri == "" {
log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
}
clientOptions := options.Client().ApplyURI(uri)
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatalf("failed to connect to the server: %v", err)
}
defer func() { _ = client.Disconnect(ctx) }()
// Set the namespace
coll := client.Database("sample_db").Collection("embeddings")
embeddings := common.GetEmbeddings(data)
docsToInsert := make([]interface{}, len(embeddings))
for i, string := range data {
docsToInsert[i] = TextWithEmbedding{
Text: string,
Embedding: embeddings[i],
}
}
result, err := coll.InsertMany(ctx, docsToInsert)
if err != nil {
log.Fatalf("failed to insert documents: %v", err)
}
fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs))
}
create-embeddings.go
package main
import (
"context"
"fmt"
"log"
"my-embeddings-project/common"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var data = []string{
"Titanic: The story of the 1912 sinking of the largest luxury liner ever built",
"The Lion King: Lion cub and future king Simba searches for his identity",
"Avatar: A marine is dispatched to the moon Pandora on a unique mission",
}
type TextWithEmbedding struct {
Text string
Embedding []float64
}
func main() {
ctx := context.Background()
if err := godotenv.Load(); err != nil {
log.Println("no .env file found")
}
// Connect to your Atlas cluster
uri := os.Getenv("ATLAS_CONNECTION_STRING")
if uri == "" {
log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
}
clientOptions := options.Client().ApplyURI(uri)
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatalf("failed to connect to the server: %v", err)
}
defer func() { _ = client.Disconnect(ctx) }()
// Set the namespace
coll := client.Database("sample_db").Collection("embeddings")
embeddings := common.GetEmbeddings(data)
docsToInsert := make([]interface{}, len(data))
for i, movie := range data {
docsToInsert[i] = TextWithEmbedding{
Text: movie,
Embedding: embeddings[i],
}
}
result, err := coll.InsertMany(ctx, docsToInsert)
if err != nil {
log.Fatalf("failed to insert documents: %v", err)
}
fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs))
}
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/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
ctx := context.Background()
if err := godotenv.Load(); err != nil {
log.Println("no .env file found")
}
// Connect to your Atlas cluster
uri := os.Getenv("ATLAS_CONNECTION_STRING")
if uri == "" {
log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
}
clientOptions := options.Client().ApplyURI(uri)
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatalf("failed to connect to the server: %v", err)
}
defer func() { _ = client.Disconnect(ctx) }()
// Set the namespace
coll := client.Database("sample_airbnb").Collection("listingsAndReviews")
filter := bson.D{
{"$and",
bson.A{
bson.D{
{"$and",
bson.A{
bson.D{{"summary", bson.D{{"$exists", true}}}},
bson.D{{"summary", bson.D{{"$ne", ""}}}},
},
}},
bson.D{{"embeddings", bson.D{{"$exists", false}}}},
}},
}
opts := options.Find().SetLimit(50)
cursor, err := coll.Find(ctx, filter, opts)
if err != nil {
log.Fatalf("failed to retrieve documents: %v", err)
}
var listings []common.Listing
if err = cursor.All(ctx, &listings); err != nil {
log.Fatalf("failed to unmarshal retrieved documents to Listing object: %v", err)
}
var summaries []string
for _, listing := range listings {
summaries = append(summaries, listing.Summary)
}
log.Println("Generating embeddings.")
embeddings := common.GetEmbeddings(summaries)
docsToUpdate := make([]mongo.WriteModel, len(listings))
for i := range listings {
docsToUpdate[i] = mongo.NewUpdateOneModel().
SetFilter(bson.D{{"_id", listings[i].ID}}).
SetUpdate(bson.D{{"$set", bson.D{{"embeddings", embeddings[i]}}}})
}
bulkWriteOptions := options.BulkWrite().SetOrdered(false)
result, err := coll.BulkWrite(context.Background(), docsToUpdate, bulkWriteOptions)
if err != nil {
log.Fatalf("failed to write embeddings to existing documents: %v", err)
}
log.Printf("Successfully added embeddings to %v documents", result.ModifiedCount)
}
2

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

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

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

    models.go
    package common
    import (
    "time"
    "go.mongodb.org/mongo-driver/bson/primitive"
    )
    type Image struct {
    ThumbnailURL string `bson:"thumbnail_url"`
    MediumURL string `bson:"medium_url"`
    PictureURL string `bson:"picture_url"`
    XLPictureURL string `bson:"xl_picture_url"`
    }
    type Host struct {
    ID string `bson:"host_id"`
    URL string `bson:"host_url"`
    Name string `bson:"host_name"`
    Location string `bson:"host_location"`
    About string `bson:"host_about"`
    ThumbnailURL string `bson:"host_thumbnail_url"`
    PictureURL string `bson:"host_picture_url"`
    Neighborhood string `bson:"host_neighborhood"`
    IsSuperhost bool `bson:"host_is_superhost"`
    HasProfilePic bool `bson:"host_has_profile_pic"`
    IdentityVerified bool `bson:"host_identity_verified"`
    ListingsCount int32 `bson:"host_listings_count"`
    TotalListingsCount int32 `bson:"host_total_listings_count"`
    Verifications []string `bson:"host_verifications"`
    }
    type Location struct {
    Type string `bson:"type"`
    Coordinates []float64 `bson:"coordinates"`
    IsLocationExact bool `bson:"is_location_exact"`
    }
    type Address struct {
    Street string `bson:"street"`
    Suburb string `bson:"suburb"`
    GovernmentArea string `bson:"government_area"`
    Market string `bson:"market"`
    Country string `bson:"Country"`
    CountryCode string `bson:"country_code"`
    Location Location `bson:"location"`
    }
    type Availability struct {
    Thirty int32 `bson:"availability_30"`
    Sixty int32 `bson:"availability_60"`
    Ninety int32 `bson:"availability_90"`
    ThreeSixtyFive int32 `bson:"availability_365"`
    }
    type ReviewScores struct {
    Accuracy int32 `bson:"review_scores_accuracy"`
    Cleanliness int32 `bson:"review_scores_cleanliness"`
    CheckIn int32 `bson:"review_scores_checkin"`
    Communication int32 `bson:"review_scores_communication"`
    Location int32 `bson:"review_scores_location"`
    Value int32 `bson:"review_scores_value"`
    Rating int32 `bson:"review_scores_rating"`
    }
    type Review struct {
    ID string `bson:"_id"`
    Date time.Time `bson:"date,omitempty"`
    ListingId string `bson:"listing_id"`
    ReviewerId string `bson:"reviewer_id"`
    ReviewerName string `bson:"reviewer_name"`
    Comments string `bson:"comments"`
    }
    type Listing struct {
    ID string `bson:"_id"`
    ListingURL string `bson:"listing_url"`
    Name string `bson:"name"`
    Summary string `bson:"summary"`
    Space string `bson:"space"`
    Description string `bson:"description"`
    NeighborhoodOverview string `bson:"neighborhood_overview"`
    Notes string `bson:"notes"`
    Transit string `bson:"transit"`
    Access string `bson:"access"`
    Interaction string `bson:"interaction"`
    HouseRules string `bson:"house_rules"`
    PropertyType string `bson:"property_type"`
    RoomType string `bson:"room_type"`
    BedType string `bson:"bed_type"`
    MinimumNights string `bson:"minimum_nights"`
    MaximumNights string `bson:"maximum_nights"`
    CancellationPolicy string `bson:"cancellation_policy"`
    LastScraped time.Time `bson:"last_scraped,omitempty"`
    CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"`
    FirstReview time.Time `bson:"first_review,omitempty"`
    LastReview time.Time `bson:"last_review,omitempty"`
    Accommodates int32 `bson:"accommodates"`
    Bedrooms int32 `bson:"bedrooms"`
    Beds int32 `bson:"beds"`
    NumberOfReviews int32 `bson:"number_of_reviews"`
    Bathrooms primitive.Decimal128 `bson:"bathrooms"`
    Amenities []string `bson:"amenities"`
    Price primitive.Decimal128 `bson:"price"`
    WeeklyPrice primitive.Decimal128 `bson:"weekly_price"`
    MonthlyPrice primitive.Decimal128 `bson:"monthly_price"`
    CleaningFee primitive.Decimal128 `bson:"cleaning_fee"`
    ExtraPeople primitive.Decimal128 `bson:"extra_people"`
    GuestsIncluded primitive.Decimal128 `bson:"guests_included"`
    Image Image `bson:"images"`
    Host Host `bson:"host"`
    Address Address `bson:"address"`
    Availability Availability `bson:"availability"`
    ReviewScores ReviewScores `bson:"review_scores"`
    Reviews []Review `bson:"reviews"`
    Embeddings []float32 `bson:"embeddings,omitempty"`
    }
    models.go
    package common
    import (
    "time"
    "go.mongodb.org/mongo-driver/bson/primitive"
    )
    type Image struct {
    ThumbnailURL string `bson:"thumbnail_url"`
    MediumURL string `bson:"medium_url"`
    PictureURL string `bson:"picture_url"`
    XLPictureURL string `bson:"xl_picture_url"`
    }
    type Host struct {
    ID string `bson:"host_id"`
    URL string `bson:"host_url"`
    Name string `bson:"host_name"`
    Location string `bson:"host_location"`
    About string `bson:"host_about"`
    ThumbnailURL string `bson:"host_thumbnail_url"`
    PictureURL string `bson:"host_picture_url"`
    Neighborhood string `bson:"host_neighborhood"`
    IsSuperhost bool `bson:"host_is_superhost"`
    HasProfilePic bool `bson:"host_has_profile_pic"`
    IdentityVerified bool `bson:"host_identity_verified"`
    ListingsCount int32 `bson:"host_listings_count"`
    TotalListingsCount int32 `bson:"host_total_listings_count"`
    Verifications []string `bson:"host_verifications"`
    }
    type Location struct {
    Type string `bson:"type"`
    Coordinates []float64 `bson:"coordinates"`
    IsLocationExact bool `bson:"is_location_exact"`
    }
    type Address struct {
    Street string `bson:"street"`
    Suburb string `bson:"suburb"`
    GovernmentArea string `bson:"government_area"`
    Market string `bson:"market"`
    Country string `bson:"Country"`
    CountryCode string `bson:"country_code"`
    Location Location `bson:"location"`
    }
    type Availability struct {
    Thirty int32 `bson:"availability_30"`
    Sixty int32 `bson:"availability_60"`
    Ninety int32 `bson:"availability_90"`
    ThreeSixtyFive int32 `bson:"availability_365"`
    }
    type ReviewScores struct {
    Accuracy int32 `bson:"review_scores_accuracy"`
    Cleanliness int32 `bson:"review_scores_cleanliness"`
    CheckIn int32 `bson:"review_scores_checkin"`
    Communication int32 `bson:"review_scores_communication"`
    Location int32 `bson:"review_scores_location"`
    Value int32 `bson:"review_scores_value"`
    Rating int32 `bson:"review_scores_rating"`
    }
    type Review struct {
    ID string `bson:"_id"`
    Date time.Time `bson:"date,omitempty"`
    ListingId string `bson:"listing_id"`
    ReviewerId string `bson:"reviewer_id"`
    ReviewerName string `bson:"reviewer_name"`
    Comments string `bson:"comments"`
    }
    type Listing struct {
    ID string `bson:"_id"`
    ListingURL string `bson:"listing_url"`
    Name string `bson:"name"`
    Summary string `bson:"summary"`
    Space string `bson:"space"`
    Description string `bson:"description"`
    NeighborhoodOverview string `bson:"neighborhood_overview"`
    Notes string `bson:"notes"`
    Transit string `bson:"transit"`
    Access string `bson:"access"`
    Interaction string `bson:"interaction"`
    HouseRules string `bson:"house_rules"`
    PropertyType string `bson:"property_type"`
    RoomType string `bson:"room_type"`
    BedType string `bson:"bed_type"`
    MinimumNights string `bson:"minimum_nights"`
    MaximumNights string `bson:"maximum_nights"`
    CancellationPolicy string `bson:"cancellation_policy"`
    LastScraped time.Time `bson:"last_scraped,omitempty"`
    CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"`
    FirstReview time.Time `bson:"first_review,omitempty"`
    LastReview time.Time `bson:"last_review,omitempty"`
    Accommodates int32 `bson:"accommodates"`
    Bedrooms int32 `bson:"bedrooms"`
    Beds int32 `bson:"beds"`
    NumberOfReviews int32 `bson:"number_of_reviews"`
    Bathrooms primitive.Decimal128 `bson:"bathrooms"`
    Amenities []string `bson:"amenities"`
    Price primitive.Decimal128 `bson:"price"`
    WeeklyPrice primitive.Decimal128 `bson:"weekly_price"`
    MonthlyPrice primitive.Decimal128 `bson:"monthly_price"`
    CleaningFee primitive.Decimal128 `bson:"cleaning_fee"`
    ExtraPeople primitive.Decimal128 `bson:"extra_people"`
    GuestsIncluded primitive.Decimal128 `bson:"guests_included"`
    Image Image `bson:"images"`
    Host Host `bson:"host"`
    Address Address `bson:"address"`
    Availability Availability `bson:"availability"`
    ReviewScores ReviewScores `bson:"review_scores"`
    Reviews []Review `bson:"reviews"`
    Embeddings []float64 `bson:"embeddings,omitempty"`
    }
  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

Atlas UI에서 sample_airbnb.listingsAndReviews 컬렉션으로 이동하여 생성된 벡터 임베딩을 확인할 수 있습니다.

1

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

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

create-embeddings.js
import { MongoClient } from 'mongodb';
import { getEmbedding } from './get-embeddings.js';
// Data to embed
const data = [
"Titanic: The story of the 1912 sinking of the largest luxury liner ever built",
"The Lion King: Lion cub and future king Simba searches for his identity",
"Avatar: A marine is dispatched to the moon Pandora on a unique mission"
]
async function run() {
// Connect to your Atlas cluster
const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING);
try {
await client.connect();
const db = client.db("sample_db");
const collection = db.collection("embeddings");
await Promise.all(data.map(async text => {
// Check if the document already exists
const existingDoc = await collection.findOne({ text: text });
// Generate an embedding by using the function that you defined
const embedding = await getEmbedding(text);
// Ingest data and embedding into Atlas
if (!existingDoc) {
await collection.insertOne({
text: text,
embedding: embedding
});
console.log(embedding);
}
}));
} catch (err) {
console.log(err.stack);
}
finally {
await client.close();
}
}
run().catch(console.dir);
2
node --env-file=.env create-embeddings.js
[ -0.04323853924870491, -0.008460805751383305, 0.012494648806750774, -0.013014335185289383, ... ]
[ -0.017400473356246948, 0.04922063276171684, -0.002836339408531785, -0.030395228415727615, ... ]
[ -0.016950927674770355, 0.013881809078156948, -0.022074559703469276, -0.02838018536567688, ... ]
node --env-file=.env create-embeddings.js
[ 0.031927742, -0.014192767, -0.021851597, 0.045498233, -0.0077904654, ... ]
[ -0.01664538, 0.013198251, 0.048684783, 0.014485021, -0.018121032, ... ]
[ 0.030449908, 0.046782598, 0.02126599, 0.025799986, -0.015830345, ... ]

참고

출력의 차원 수는 가독성을 위해 일부만 표시되었습니다.

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

참고

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

1

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

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

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

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

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

create-embeddings.js
import { MongoClient } from 'mongodb';
import { getEmbedding } from './get-embeddings.js';
// Connect to your Atlas cluster
const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING);
async function run() {
try {
await client.connect();
const db = client.db("sample_airbnb");
const collection = db.collection("listingsAndReviews");
// Filter to exclude null or empty summary fields
const filter = { "summary": { "$nin": [ null, "" ] } };
// Get a subset of documents from the collection
const documents = await collection.find(filter).limit(50).toArray();
// Create embeddings from a field in the collection
let updatedDocCount = 0;
console.log("Generating embeddings for documents...");
await Promise.all(documents.map(async doc => {
// Generate an embedding by using the function that you defined
const embedding = await getEmbedding(doc.summary);
// Update the document with a new embedding field
await collection.updateOne({ "_id": doc._id },
{
"$set": {
"embedding": embedding
}
}
);
updatedDocCount += 1;
}));
console.log("Count of documents updated: " + updatedDocCount);
} catch (err) {
console.log(err.stack);
}
finally {
await client.close();
}
}
run().catch(console.dir);
2
node --env-file=.env create-embeddings.js
Generating embeddings for documents...
Count of documents updated: 50

Atlas UI 에서 sample_airbnb.listingsAndReviews 컬렉션 으로 이동하고 문서 의 필드를 확장하면 생성되는 벡터 임베딩을 볼 수 있습니다.

1

다음 코드를 사용하여 새로운 데이터에서 임베딩을 생성합니다.

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

import pymongo
# Connect to your Atlas cluster
mongo_client = pymongo.MongoClient("<connection-string>")
db = mongo_client["sample_db"]
collection = db["embeddings"]
# Sample data
data = [
"Titanic: The story of the 1912 sinking of the largest luxury liner ever built",
"The Lion King: Lion cub and future king Simba searches for his identity",
"Avatar: A marine is dispatched to the moon Pandora on a unique mission"
]
# Ingest data into Atlas
inserted_doc_count = 0
for text in data:
embedding = get_embedding(text)
collection.insert_one({ "text": text, "embedding": embedding })
inserted_doc_count += 1
print(f"Inserted {inserted_doc_count} documents.")
Inserted 3 documents.
2

<connection-string>을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.

참고

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

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

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

참고

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

1

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

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

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

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

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

import pymongo
# Connect to your Atlas cluster
mongo_client = pymongo.MongoClient("<connection-string>")
db = mongo_client["sample_airbnb"]
collection = db["listingsAndReviews"]
# Filter to exclude null or empty summary fields
filter = { "summary": {"$nin": [ None, "" ]} }
# Get a subset of documents in the collection
documents = collection.find(filter).limit(50)
# Update each document with a new embedding field
updated_doc_count = 0
for doc in documents:
embedding = get_embedding(doc["summary"])
collection.update_one( { "_id": doc["_id"] }, { "$set": { "embedding": embedding } } )
updated_doc_count += 1
print(f"Updated {updated_doc_count} documents.")
Updated 50 documents.
2

<connection-string>을 Atlas 클러스터의 SRV 연결 문자열로 바꿉니다.

참고

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

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

Atlas UI 에서 sample_airbnb.listingsAndReviews 컬렉션 으로 이동하고 문서 의 필드를 확장하면 생성되는 벡터 임베딩을 볼 수 있습니다.

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

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

1

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

embedding 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 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/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    )
    func main() {
    ctx := context.Background()
    if err := godotenv.Load(); err != nil {
    log.Println("no .env file found")
    }
    // Connect to your Atlas cluster
    uri := os.Getenv("ATLAS_CONNECTION_STRING")
    if uri == "" {
    log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
    }
    clientOptions := options.Client().ApplyURI(uri)
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
    log.Fatalf("failed to connect to the server: %v", err)
    }
    defer func() { _ = client.Disconnect(ctx) }()
    // Set the namespace
    coll := client.Database("sample_db").Collection("embeddings")
    indexName := "vector_index"
    opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch")
    type vectorDefinitionField struct {
    Type string `bson:"type"`
    Path string `bson:"path"`
    NumDimensions int `bson:"numDimensions"`
    Similarity string `bson:"similarity"`
    }
    type vectorDefinition struct {
    Fields []vectorDefinitionField `bson:"fields"`
    }
    indexModel := mongo.SearchIndexModel{
    Definition: vectorDefinition{
    Fields: []vectorDefinitionField{{
    Type: "vector",
    Path: "embedding",
    NumDimensions: <dimensions>,
    Similarity: "euclidean"}},
    },
    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/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    )
    type TextAndScore struct {
    Text string `bson:"text"`
    Score float32 `bson:"score"`
    }
    func main() {
    ctx := context.Background()
    // Connect to your Atlas cluster
    if err := godotenv.Load(); err != nil {
    log.Println("no .env file found")
    }
    // Connect to your Atlas cluster
    uri := os.Getenv("ATLAS_CONNECTION_STRING")
    if uri == "" {
    log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
    }
    clientOptions := options.Client().ApplyURI(uri)
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
    log.Fatalf("failed to connect to the server: %v", err)
    }
    defer func() { _ = client.Disconnect(ctx) }()
    // Set the namespace
    coll := client.Database("sample_db").Collection("embeddings")
    query := "ocean tragedy"
    queryEmbedding := common.GetEmbeddings([]string{query})
    pipeline := mongo.Pipeline{
    bson.D{
    {"$vectorSearch", bson.D{
    {"queryVector", queryEmbedding[0]},
    {"index", "vector_index"},
    {"path", "embedding"},
    {"exact", true},
    {"limit", 5},
    }},
    },
    bson.D{
    {"$project", bson.D{
    {"_id", 0},
    {"text", 1},
    {"score", bson.D{
    {"$meta", "vectorSearchScore"},
    }},
    }},
    },
    }
    // Run the pipeline
    cursor, err := coll.Aggregate(ctx, pipeline)
    if err != nil {
    log.Fatalf("failed to run aggregation: %v", err)
    }
    defer func() { _ = cursor.Close(ctx) }()
    var matchingDocs []TextAndScore
    if err = cursor.All(ctx, &matchingDocs); err != nil {
    log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err)
    }
    for _, doc := range matchingDocs {
    fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score)
    }
    }
    vector-query.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 TextAndScore struct {
    Text string `bson:"text"`
    Score float64 `bson:"score"`
    }
    func main() {
    ctx := context.Background()
    // Connect to your Atlas cluster
    if err := godotenv.Load(); err != nil {
    log.Println("no .env file found")
    }
    // Connect to your Atlas cluster
    uri := os.Getenv("ATLAS_CONNECTION_STRING")
    if uri == "" {
    log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.")
    }
    clientOptions := options.Client().ApplyURI(uri)
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
    log.Fatalf("failed to connect to the server: %v", err)
    }
    defer func() { _ = client.Disconnect(ctx) }()
    // Set the namespace
    coll := client.Database("sample_db").Collection("embeddings")
    query := "ocean tragedy"
    queryEmbedding := common.GetEmbeddings([]string{query})
    pipeline := mongo.Pipeline{
    bson.D{
    {"$vectorSearch", bson.D{
    {"queryVector", queryEmbedding[0]},
    {"index", "vector_index"},
    {"path", "embedding"},
    {"exact", true},
    {"limit", 5},
    }},
    },
    bson.D{
    {"$project", bson.D{
    {"_id", 0},
    {"text", 1},
    {"score", bson.D{
    {"$meta", "vectorSearchScore"},
    }},
    }},
    },
    }
    // Run the pipeline
    cursor, err := coll.Aggregate(ctx, pipeline)
    if err != nil {
    log.Fatalf("failed to run aggregation: %v", err)
    }
    defer func() { _ = cursor.Close(ctx) }()
    var matchingDocs []TextAndScore
    if err = cursor.All(ctx, &matchingDocs); err != nil {
    log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err)
    }
    for _, doc := range matchingDocs {
    fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score)
    }
    }
  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: "euclidean"}},
    },
    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 필드를 벡터 유형으로 지정하고 유사성 측정값을 euclidean으로 지정하는 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": "euclidean",
    "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.4551968574523926}
    {"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4050074517726898}
    {"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.3594386577606201}
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": "euclidean",
    "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 필드를 벡터 유형으로, 유사성 측정값을 euclidean으로, 차원 수를 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": "euclidean",
    "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 필드를 벡터 유형으로, 유사성 측정값을 euclidean으로, 차원 수를 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": "euclidean",
    "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)
{"text": "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "score": 0.5166476964950562}
{"text": "Avatar: A marine is dispatched to the moon Pandora on a unique mission", "score": 0.4587385058403015}
{"text": "The Lion King: Lion cub and future king Simba searches for his identity", "score": 0.41374602913856506}
# Generate embedding for the search query
query_embedding = get_embedding("ocean tragedy")
# Sample vector search pipeline
pipeline = [
{
"$vectorSearch": {
"index": "vector_index",
"queryVector": query_embedding,
"path": "embedding",
"exact": True,
"limit": 5
}
},
{
"$project": {
"_id": 0,
"text": 1,
"score": {
"$meta": "vectorSearchScore"
}
}
}
]
# Execute the search
results = collection.aggregate(pipeline)
# Print results
for i in results:
print(i)
{"text":"Titanic: The story of the 1912 sinking of the largest luxury liner ever built","score":0.4551968574523926}
{"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4050074517726898}
{"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.3594386577606201}
1

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

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

    이 코드는 embedding 필드를 벡터 유형으로, 유사성 측정값을 euclidean으로, 차원 수를 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": "euclidean",
    "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 필드를 벡터 유형으로, 유사성 측정값을 euclidean으로, 차원 수를 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": "euclidean",
    "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.5372996926307678}
{"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.5297179818153381}
{"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.5234108567237854}
{"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.5171462893486023}
{"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.5095183253288269}
# 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: 토큰 수 단일 임베딩으로 압축할 수 있습니다.

    대부분의 시맨틱 검색 사용 사례에서는 최대 토큰 길이가 512 인 경우에 사용할 수 있는데, 이는 일반적으로 단일 임베딩에서 한 문단의 텍스트(~100 토큰) 이상을 원하지 않기 때문입니다.

  • 모델 크기: 기가바이트 단위의 모델 크기입니다.

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

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

    점수가 높을수록 모델이 검색된 결과 목록에서 관련 문서의 순위를 더 높게 지정하는 것이 더 우수하다는 의미입니다. 이 점수는 RAG 애플리케이션용 모델을 선택할 때 중요합니다.

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

  • 함수와 스크립트를 테스트합니다.

    임베딩을 생성하려면 시간과 계산 리소스가 필요합니다. 대규모 데이터 세트 또는 컬렉션에서 임베딩을 생성하기 전에 임베딩 함수 또는 스크립트가 데이터의 작은 하위 집합에서 예상대로 작동하는지 테스트합니다.

  • 임베딩을 일괄적으로 생성합니다.

    대규모 데이터 세트나 문서가 많은 컬렉션 에서 임베딩을 생성하려는 경우, 메모리 문제를 방지하고 성능을 최적화하려면 배치로 생성하세요.

  • 성능을 평가합니다.

    테스트 쿼리를 실행하여 검색 결과가 관련성이 있고 정확하게 순위가 매겨졌는지 확인합니다.

    다양한 임베딩 모델을 실험하여 벡터 검색 쿼리의 성능을 개선할 수도 있습니다. 자세한 내용은 LLM 지원서 평가 방법을 참조하세요.

임베딩에 문제가 발생하는 경우 다음 전략을 고려하세요.

  • 환경을 확인합니다.

    필요한 종속성이 설치되어 있고 최신 상태인지 확인합니다. 라이브러리 버전이 충돌하면 예기치 않은 동작이 발생할 수 있습니다. 새 환경을 만들고 필요한 패키지만 설치하여 충돌이 없는지 확인합니다.

    참고

    Colab을 사용하는 경우 노트북 세션의 IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요.

  • 메모리 사용량을 모니터링합니다.

    성능 문제가 발생하는 경우 RAM, CPU 및 디스크 사용량을 확인하여 잠재적인 병목 현상을 식별합니다. Colab 또는 Jupyter 노트북과 같은 호스팅 환경의 인스턴스 에 충분한 리소스가 프로비저닝되어 있는지 확인하고 필요한 경우 인스턴스 를 업그레이드 합니다.

  • 일관적인 크기를 보장합니다.

    Atlas Vector Search 인덱스 정의가 Atlas 에 저장된 임베딩의 크기와 일치하고 쿼리 임베딩이 인덱싱된 임베딩의 크기와 일치하는지 확인합니다. 그렇지 않으면 벡터 검색 쿼리를 실행 때 오류가 발생할 수 있습니다.

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

임베딩을 BSON 벡터로 변환하면 Atlas에서 벡터를 효율적으로 저장하고 수집할 수 있습니다. 자세한 내용은 Atlas에서 효율적인 벡터 저장 및 수집을 위한 데이터 설정을 참조하세요.

돌아가기

Atlas Vector Search 빠른 시작