Como criar incorporações de vetor
Nesta página
Você pode armazenar incorporações de vetores junto aos seus outros dados no Atlas. Essas incorporações capturam relacionamentos significativos nos seus dados e permitem que você execute pesquisas semânticas e implemente o RAG com o Atlas Vector Search.
Começar
Use o tutorial a seguir para aprender como criar incorporações vetoriais e consultá-las usando o Atlas Vector Search. Especificamente, você executa as seguintes ações:
Defina uma função que utiliza um modelo de incorporação para gerar incorporações vetoriais.
Crie incorporações a partir dos seus dados e armazene-as no Atlas.
Crie incorporações a partir de seus termos de pesquisa e execute uma query de pesquisa vetorial.
Para aplicativos de produção, normalmente você escreve um script para gerar incorporações vetoriais. Você pode começar com o código de amostra nesta página e personalizá-lo para seu caso de uso.
➤ Use o menu suspenso Selecione sua linguagem para definir o idioma dos exemplos nesta página.
Pré-requisitos
Para concluir este tutorial, você deve ter o seguinte:
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs). Garanta que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas . Para saber mais, consulte Criar um cluster.
Um terminal e editor de código para executar seu projeto C#.
.NET 8.0 ou superior instalado.
Um token de acesso da Hugging Face ou chave de API da OpenAI.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs). Garanta que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas . Para saber mais, consulte Criar um cluster.
Um terminal e editor de código para executar seu projeto Go.
Go instalado.
Um token de acesso da Hugging Face ou chave de API da OpenAI.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs). Garanta que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas . Para saber mais, consulte Criar um cluster.
Java Development Kit (JDK) versão 8 ou posterior.
Um ambiente para configurar e executar um aplicação Java . Recomendamos que você use um ambiente de desenvolvimento integrado (IDE) como IntelliJ IDEA ou Eclipse IDE para configurar Maven ou Gradle para construir e executar seu projeto.
Uma das seguintes opções:
Um token de acesso ao face com acesso de leitura
Uma chave de API OpenAI. Você deve ter uma conta paga do OpenAI com créditos disponíveis para solicitações de API. Para saber mais sobre como registrar uma conta OpenAI, consulte o site da API OpenAI.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs). Garanta que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas . Para saber mais, consulte Criar um cluster.
Um editor de terminal e código para executar seu projeto Node.js.
npm e Node.js instalado.
Se você estiver usando modelos da OpenAI, você deve ter uma chave de API da OpenAI.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs). Garanta que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas . Para saber mais, consulte Criar um cluster.
Um ambiente para executar notebooks Python interativos, como o VS Code ou Colab.
Se você estiver usando modelos da OpenAI, você deve ter uma chave de API da OpenAI.
Definir uma função de incorporação
Defina suas variáveis de ambiente.
Exporte suas variáveis de ambiente, set
elas no PowerShell ou use o gerenciador de variáveis de ambiente do seu IDE para disponibilizar a string de conexão e o token de acesso do HuggingFace para seu projeto.
export HUGGINGFACE_ACCESS_TOKEN="<access-token>" export ATLAS_CONNECTION_STRING="<connection-string>"
Substitua o valor do espaço reservado <access-token>
pelo token de acesso do Abraçando a Face.
Substitua o <connection-string>
valor do espaço reservado pela string de conexão SRVdo seu Atlas cluster.
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina uma função para gerar incorporações vetoriais.
Crie uma nova classe em um arquivo do mesmo nome denominado AIService.cs
e cole o seguinte código. Este código define uma Tarefa assíncrona chamada GetEmbeddingsAsync
para gerar uma array de incorporações para uma array de entradas de string fornecidas. Essa função usa o modelo de incorporação mxbai-embed-large-v.1
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; } }
Observação
503 ao chamar modelos de Face Abraços
Ocasionalmente, você pode receber erros 503 ao chamar modelos a partir do hub de modelos Hugging Face. Para resolver esse problema, tente novamente após um breve intervalo.
Defina suas variáveis de ambiente.
Exporte suas variáveis de ambienteset
para o PowerShell ou use o gerenciador de variáveis de ambiente do seu IDE para disponibilizar a string de conexão e o token de acesso do HuggingFace para seu projeto.
export OPENAI_API_KEY="<api-key>" export ATLAS_CONNECTION_STRING="<connection-string>"
Substitua o valor do espaço reservado <api-key>
por sua chave de API OpenAI.
Substitua o <connection-string>
valor do espaço reservado pela string de conexão SRVdo seu Atlas cluster.
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina uma função para gerar incorporações vetoriais.
Crie uma nova classe em um arquivo do mesmo nome denominado AIService.cs
e cole o seguinte código. Este código define uma Tarefa assíncrona chamada GetEmbeddingsAsync
para gerar uma array de incorporações para uma array de entradas de string fornecidas. Esta função usa o modelo text-embedding-3-small
do OpenAI para gerar uma incorporação para uma determinada entrada.
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; } }
Nesta seção, você define uma função para gerar incorporações vetoriais usando um modelo incorporado. Selecione uma guia com base no fato de você desejar usar um modelo de incorporação de código aberto ou um modelo proprietário, como OpenAI.
Observação
Os modelos de incorporação de código aberto são gratuitos e podem ser carregados localmente a partir do seu aplicação. Modelos proprietários exigem uma chave de API para acessar os modelos.
Crie um .env
arquivo para gerenciar segredos.
Em seu projeto, crie um arquivo .env
para armazenar sua string de conexão do Atlas e o token de acesso do Hugging Face.
HUGGINGFACEHUB_API_TOKEN = "<access-token>" ATLAS_CONNECTION_STRING = "<connection-string>"
Substitua o valor do espaço reservado <access-token>
pelo token de acesso do Abraçando a Face.
Substitua o <connection-string>
valor do espaço reservado pela string de conexão SRVdo seu Atlas cluster.
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina uma função para gerar incorporações vetoriais.
Crie um diretório no seu projeto chamado
common
para armazenar o código comum que você usará nas etapas posteriores:mkdir common && cd common Crie um arquivo chamado
get-embeddings.go
e cole o código a seguir. Esse código define uma função chamadaGetEmbeddings
para gerar uma incorporação para uma determinada entrada. Essa função especifica:A tarefa
feature-extraction
usando a porta Go da biblioteca do LangChain. Para saber mais, consulte a documentação das Tarefas na documentação do LangChain JavaScript.O modelo de incorporação mxbai-embed-large-v1.
get-embeddings.gopackage common import ( "context" "log" "github.com/tmc/langchaingo/embeddings/huggingface" ) func GetEmbeddings(documents []string) [][]float32 { hf, err := huggingface.NewHuggingface( huggingface.WithModel("mixedbread-ai/mxbai-embed-large-v1"), huggingface.WithTask("feature-extraction")) if err != nil { log.Fatalf("failed to connect to Hugging Face: %v", err) } embs, err := hf.EmbedDocuments(context.Background(), documents) if err != nil { log.Fatalf("failed to generate embeddings: %v", err) } return embs } Observação
503 ao chamar modelos de Face Abraços
Ocasionalmente, você pode receber erros 503 ao chamar modelos a partir do hub de modelos Hugging Face. Para resolver esse problema, tente novamente após um breve intervalo.
Volte para o diretório raiz do projeto principal.
cd ../
Crie um .env
arquivo para gerenciar segredos.
No seu projeto, crie um arquivo .env
para armazenar sua string de conexão e o token de API OpenAI.
OPENAI_API_KEY = "<api-key>" ATLAS_CONNECTION_STRING = "<connection-string>"
Substitua os valores de espaço reservado <api-key>
e <connection-string>
por sua chave de API da OpenAI e a string de conexão SRV pra seu Cluster do Atlas. Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Observação
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina uma função para gerar incorporações vetoriais.
Crie um diretório em seu projeto chamado
common
para armazenar o código que você usará em várias etapas:mkdir common && cd common Crie um arquivo denominado
get-embeddings.go
e cole o seguinte código. Esse código define uma função chamadaGetEmbeddings
que usa o modelotext-embedding-3-small
da OpenAI para gerar uma incorporação para uma determinada entrada.get-embeddings.gopackage common import ( "context" "log" "github.com/milosgajdos/go-embeddings/openai" ) func GetEmbeddings(docs []string) [][]float64 { c := openai.NewClient() embReq := &openai.EmbeddingRequest{ Input: docs, Model: openai.TextSmallV3, EncodingFormat: openai.EncodingFloat, } embs, err := c.Embed(context.Background(), embReq) if err != nil { log.Fatalf("failed to connect to OpenAI: %v", err) } var vectors [][]float64 for _, emb := range embs { vectors = append(vectors, emb.Vector) } return vectors } Volte para o diretório raiz do projeto principal.
cd ../
Nesta seção, você define uma função para gerar incorporações vetoriais usando um modelo incorporado. Selecione uma guia com base no fato de você desejar usar um modelo de incorporação de código aberto ou um modelo proprietário, como OpenAI.
Observação
Os modelos de incorporação de código aberto são gratuitos e podem ser carregados localmente a partir do seu aplicação. Modelos proprietários exigem uma chave de API para acessar os modelos.
Crie seu projeto Java e instale dependências.
No seu IDE, crie um projeto Java usando Maven ou Gradle.
Adicione as seguintes dependências, dependendo do seu gerenciador de pacote :
Se você estiver utilizando o Maven, adicione as seguintes dependências à array
dependencies
no arquivopom.xml
do seu projeto: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> Se você estiver usando o Gradle, adicione o seguinte à array
dependencies
no arquivobuild.gradle
do seu projeto:build.gradledependencies { // MongoDB Java Sync Driver v5.2.0 or later implementation 'org.mongodb:mongodb-driver-sync:[5.2.0,)' // Java library for working with Hugging Face models implementation 'dev.langchain4j:langchain4j-hugging-face:0.35.0' } Execute seu gerenciador de pacote para instalar as dependências em seu projeto.
Defina suas variáveis de ambiente.
Observação
Este exemplo define as variáveis do projeto no IDE. Os aplicativos de produção podem gerenciar variáveis de ambiente por meio de uma configuração de sistema, pipeline CI/CD ou gerenciador de segredos, mas você pode adaptar o código fornecido para se adequar ao seu caso de uso.
No seu IDE, crie um novo modelo de configuração e adicione as seguintes variáveis ao seu projeto:
Se você estiver usando o IntelliJ IDEA, crie um novo modelo de configuração de execução do Application e adicione suas variáveis como valores separados por ponto e vírgula no campo Environment variables (por exemplo,
FOO=123;BAR=456
). Aplique as alterações e clique em OK.Para saber mais, consulte a seção Criar uma configuração de execução/depuração a partir de um modelo da documentação do IntelliJ IDEA.
Se você estiver usando o Eclipse, crie uma nova configuração de inicialização Java Application e, em seguida, adicione cada variável como um novo par de valores-chave na guia Environment. Aplique as alterações e clique em OK.
Para saber mais, consulte a seção Criando uma configuração de inicialização do aplicação Java da documentação do IDE do Eclipse.
HUGGING_FACE_ACCESS_TOKEN=<access-token> ATLAS_CONNECTION_STRING=<connection-string>
Atualize os espaços reservados com os seguintes valores:
Substitua o valor do espaço reservado ``<access-token>`` pelo seu token de acesso do Abraçando a Face.
Substitua o
<connection-string>
valor do espaço reservado pela string de conexão SRVdo seu Atlas cluster.Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina um método para gerar incorporações vetoriais.
Crie um arquivo denominado EmbeddingProvider.java
e cole o seguinte código.
Este código define dois métodos para gerar incorporações para uma determinada entrada usando o modelo de incorporação de código aberto mxbai-embed-large-v:1
Várias Entradas: O
getEmbeddings
método aceita uma array de entradas de texto (List<String>
), permitindo criar várias incorporações em uma única chamada de API. O método converte as arrays de floats fornecidas pela API em arrays BSON de double para armazenamento em seu Atlas cluster.Entrada única: o
getEmbedding
método aceita umString
único, que representa uma query que você deseja fazer em relação aos dados vetoriais. O método converte a array de flutuantes fornecida pela API em uma array BSON de valores duplos para usar ao fazer query em sua coleção.
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()); } }
Crie seu projeto Java e instale dependências.
No seu IDE, crie um projeto Java usando Maven ou Gradle.
Adicione as seguintes dependências, dependendo do seu gerenciador de pacote :
Se você estiver utilizando o Maven, adicione as seguintes dependências à array
dependencies
no arquivopom.xml
do seu projeto: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> Se você estiver usando o Gradle, adicione o seguinte à array
dependencies
no arquivobuild.gradle
do seu projeto:build.gradledependencies { // MongoDB Java Sync Driver v5.2.0 or later implementation 'org.mongodb:mongodb-driver-sync:[5.2.0,)' // Java library for working with OpenAI models implementation 'dev.langchain4j:langchain4j-open-ai:0.35.0' } Execute seu gerenciador de pacote para instalar as dependências em seu projeto.
Defina suas variáveis de ambiente.
Observação
Este exemplo define as variáveis do projeto no IDE. Os aplicativos de produção podem gerenciar variáveis de ambiente por meio de uma configuração de sistema, pipeline CI/CD ou gerenciador de segredos, mas você pode adaptar o código fornecido para se adequar ao seu caso de uso.
No seu IDE, crie um novo modelo de configuração e adicione as seguintes variáveis ao seu projeto:
Se você estiver usando o IntelliJ IDEA, crie um novo modelo de configuração de execução do Application e adicione suas variáveis como valores separados por ponto e vírgula no campo Environment variables (por exemplo,
FOO=123;BAR=456
). Aplique as alterações e clique em OK.Para saber mais, consulte a seção Criar uma configuração de execução/depuração a partir de um modelo da documentação do IntelliJ IDEA.
Se você estiver usando o Eclipse, crie uma nova configuração de inicialização Java Application e, em seguida, adicione cada variável como um novo par de valores-chave na guia Environment. Aplique as alterações e clique em OK.
Para saber mais, consulte a seção Criando uma configuração de inicialização do aplicação Java da documentação do IDE do Eclipse.
OPEN_AI_API_KEY=<api-key> ATLAS_CONNECTION_STRING=<connection-string>
Atualize os espaços reservados com os seguintes valores:
Substitua o valor do espaço reservado ``<api-key>`` por sua chave de API OpenAI.
Substitua o
<connection-string>
valor do espaço reservado pela string de conexão SRVdo seu Atlas cluster.Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Defina um método para gerar incorporações vetoriais.
Crie um arquivo denominado EmbeddingProvider.java
e cole o seguinte código.
Este código define dois métodos para gerar incorporações para uma determinada entrada usando o modelo de incorporação text-embedding-3-small OpenAI:
Várias Entradas: O
getEmbeddings
método aceita uma array de entradas de texto (List<String>
), permitindo criar várias incorporações em uma única chamada de API. O método converte as arrays de floats fornecidas pela API em arrays BSON de double para armazenamento em seu Atlas cluster.Entrada única: o
getEmbedding
método aceita umString
único, que representa uma query que você deseja fazer em relação aos dados vetoriais. O método converte a array de flutuantes fornecida pela API em uma array BSON de valores duplos para usar ao fazer query em sua coleção.
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()); } }
Nesta seção, você define uma função para gerar incorporações vetoriais usando um modelo incorporado. Selecione uma guia com base no fato de você desejar usar um modelo de incorporação de código aberto ou um modelo proprietário, como OpenAI.
Observação
Os modelos de incorporação de código aberto são gratuitos e podem ser carregados localmente a partir do seu aplicação. Modelos proprietários exigem uma chave de API para acessar os modelos.
Atualize seu arquivo package.json
.
Configure seu projeto para usar módulos ES adicionando "type": "module"
ao seu arquivo package.json
e salvando-o.
{ "type": "module", // other fields... }
Crie um arquivo .env
.
No seu projeto, crie um arquivo .env
para armazenar sua string de conexão do Atlas.
ATLAS_CONNECTION_STRING = "<connection-string>"
Substitua o valor de espaço reservado <connection-string>
pela string de conexão SRV do seu cluster Atlas. Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Observação
Requisitos mínimos de versão do Node.js
O Node.js v20.x introduziu a opção --env-file
. Se você estiver usando uma versão mais antiga do Node.js, adicione o pacote dotenv
ao seu projeto ou use um método diferente para gerenciar suas variáveis de ambiente.
Defina uma função para gerar incorporações vetoriais.
Crie um arquivo chamado get-embeddings.js
e cole o código a seguir. Esse código define uma função denominada para gerar uma incorporação para uma determinada entrada. Essa função especifica:
A tarefa
feature-extraction
da biblioteca transformers.js do Hugging Face. Para saber mais, consulte Tarefas.
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); }
Atualize seu arquivo package.json
.
Configure seu projeto para usar módulos ES adicionando "type": "module"
ao seu arquivo package.json
e salvando-o.
{ "type": "module", // other fields... }
Crie um arquivo .env
.
Em seu projeto, crie um arquivo .env
para armazenar sua string de conexão do Atlas e a chave de API da OpenAI.
OPENAI_API_KEY = "<api-key>" ATLAS_CONNECTION_STRING = "<connection-string>"
Substitua os valores de espaço reservado <api-key>
e <connection-string>
por sua chave de API da OpenAI e a string de conexão SRV pra seu Cluster do Atlas. Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Observação
Requisitos mínimos de versão do Node.js
O Node.js v20.x introduziu a opção --env-file
. Se você estiver usando uma versão mais antiga do Node.js, adicione o pacote dotenv
ao seu projeto ou use um método diferente para gerenciar suas variáveis de ambiente.
Defina uma função para gerar incorporações vetoriais.
Crie um arquivo denominado get-embeddings.js
e cole o seguinte código. Esse código define uma função chamada getEmbedding
que usa o modelo text-embedding-3-small
da OpenAI para gerar uma incorporação para uma determinada entrada.
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; }
Nesta seção, você define uma função para gerar incorporações vetoriais usando um modelo incorporado. Selecione uma aba com base no fato de você desejar usar um modelo de incorporação de código aberto da Nomic ou um modelo proprietário da OpenAI.
O exemplo de código aberto também inclui uma função para converter suas incorporações em binData
vetores BSON para processamento eficiente. Somente determinados modelos de incorporação suportam saídas de vetor de bytes. Para incorporar modelos que não o fazem, como modelos do OpenAI, habilite a quantização automática ao criar o índice do Atlas Vector Search .
Observação
Os modelos de incorporação de código aberto são gratuitos e podem ser carregados localmente a partir do seu aplicação. Modelos proprietários exigem uma chave de API para acessar os modelos.
Configure o ambiente.
Crie um notebook Python interativo salvando um arquivo com a extensão .ipynb
e, em seguida, execute o seguinte comando no notebook para instalar as dependências:
!pip install --quiet --upgrade sentence-transformers pymongo einops
Installing collected packages: dnspython, pymongo Successfully installed dnspython-2.7.0 pymongo-4.10.1
Defina a função para gerar incorporações vetoriais.
Cole e execute o seguinte código no seu notebook para criar uma função que gera incorporações vetoriais usando um modelo de incorporação de código aberto da Nomic AI. Este código faz o seguinte:
Carrega o modelo de incorporação de1nomic-embed-text-v.
Cria uma função denominada
get_embedding
que utiliza o modelo para gerarfloat32
, que é configurado como a precisão padrão,int8
ouint1
incorporações para uma determinada entrada de texto.
from sentence_transformers import SentenceTransformer from sentence_transformers.quantization import quantize_embeddings # Load the embedding model model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True) # Define a function to generate embeddings in multiple precisions def get_embedding(data, precision="float32"): return model.encode(data, precision=precision)
Defina a função para converter incorporações vetoriais.
Cole e execute o código a seguir em seu bloco de anotações para criar uma função que converta incorporações vetoriais usando o driver do PyMongo . A função chamada generate_bson_vector
para converter as incorporações de fidelidade total float32
nosint8
int1
vector
subtipos BSON, e para processamento eficiente dos dados vetoriais.
from bson.binary import Binary # Generate BSON vector using `BinaryVectorDtype` def generate_bson_vector(vector, vector_dtype): return Binary.from_vector(vector, vector_dtype)
Defina a função para criar documentos com os embeddings.
Cole e execute o seguinte código no seu bloco de anotações para criar uma função chamada create_docs_with_bson_vector_embeddings
que cria documentos com os embeddings.
from bson.binary import Binary # Function to create documents with BSON vector embeddings def create_docs_with_bson_vector_embeddings(bson_float32, bson_int8, bson_int1, data): docs = [] for i, (bson_f32_emb, bson_int8_emb, bson_int1_emb, text) in enumerate(zip(bson_float32, bson_int8, bson_int1, data)): doc = { "_id": i, "data": text, "BSON-Float32-Embedding": bson_f32_emb, "BSON-Int8-Embedding": bson_int8_emb, "BSON-Int1-Embedding": bson_int1_emb, } docs.append(doc) return docs
Teste a função para gerar incorporações.
Cole e execute o seguinte código em seu bloco de anotações para testar a função de gerar incorporações usando a IA Nomic.
Este código gera embeddings float32
, int8
, int1
para as strings foo
e bar
.
# Example generating embeddings for the strings "foo" and "bar" data = ["foo", "bar"] float32_embeddings = get_embedding(data, "float32") int8_embeddings = get_embedding(data, "int8") int1_embeddings = get_embedding(data, "ubinary") print("Float32 Embedding:", float32_embeddings) print("Int8 Embedding:", int8_embeddings) print("Int1 Embedding (binary representation):", int1_embeddings)
Float32 Embedding: [ [-0.02980827 0.03841474 -0.02561123 ... -0.0532876 -0.0335409 -0.02591543] [-0.02748881 0.03717749 -0.03104552 ... 0.02413219 -0.02402252 0.02810651] ] Int8 Embedding: [ [-128 127 127 ... -128 -128 -128] [ 126 -128 -128 ... 127 126 127] ] Int1 Embedding (binary representation): [ [ 77 30 4 131 15 123 146 ... 159 142 205 23 119 120] [ 79 82 208 180 45 79 209 ... 158 100 141 189 166 173] ]
Teste a função para converter incorporações em vetores BSON.
Cole e execute o código a seguir em seu bloco de anotações para testar a função de conversão de incorporações em vetores BSON usando o driver PyMongo.
Este código quantiza suas incorporações float32
, int8
e int1
para as strings foo
e bar
.
from bson.binary import Binary, BinaryVectorDtype bson_float32_embeddings = [] bson_int8_embeddings = [] bson_int1_embeddings = [] for (f32_emb, int8_emb, int1_emb) in zip(float32_embeddings, int8_embeddings, int1_embeddings): bson_float32_embeddings.append(generate_bson_vector(f32_emb, BinaryVectorDtype.FLOAT32)) bson_int8_embeddings.append(generate_bson_vector(int8_emb, BinaryVectorDtype.INT8)) bson_int1_embeddings.append(generate_bson_vector(int1_emb, BinaryVectorDtype.PACKED_BIT)) # Print the embeddings print(f"The converted bson_float32_new_embedding is: {bson_float32_embeddings}") print(f"The converted bson_int8_new_embedding is: {bson_int8_embeddings}") print(f"The converted bson_int1_new_embedding is: {bson_int1_embeddings}")
The converted bson_float32_new_embedding is: [Binary(b'\'\x00x0\xf4\ ... x9bL\xd4\xbc', 9), Binary(b'\'\x007 ... \x9e?\xe6<', 9)] The converted bson_int8_new_embedding is: [Binary(b'\x03\x00\x80\x7f\ ... x80\x80', 9), Binary(b'\x03\x00~\x80 ... \x7f', 9)] The converted bson_int1_new_embedding is: [Binary(b'\x10\x00M\x1e\ ... 7wx', 9), Binary(b'\x10\x00OR\ ... \xa6\xad', 9)]
Defina uma função para gerar incorporações vetoriais.
Cole e execute o código a seguir em seu notebook para criar uma função que gere embeddings vetoriais usando um modelo de embedding proprietário da OpenAI. Substitua <api-key>
pela sua chave de API OpenAI. Este código faz o seguinte:
Especifica o modelo de incorporação
text-embedding-3-small
.Cria uma função chamada
get_embedding
que chama a API do modelo para gerar uma incorporação para uma determinada entrada de texto.Testa a função gerando uma única incorporação para a string
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, ... ]
Dica
Veja também:
Para mais detalhes da API e uma lista de modelos disponíveis, consulte a documentação da OpenAI.
Criar incorporações a partir de dados
Nesta seção, você cria incorporações vetoriais a partir dos seus dados utilizando a função que você definiu e então armazena estas incorporações em uma coleção no Atlas.
Selecione uma guia com base no desejo de criar incorporações a partir de novos dados ou de dados existentes que você já possui no Atlas.
Defina uma DataService
classe .
Crie uma nova classe em um arquivo do mesmo nome denominado DataService.cs
e cole o seguinte código. Esse código define uma tarefa assíncrona chamada AddDocumentsAsync
adicionar documentos ao Atlas. Esta função usa o método Collection.InsertManyAsync() C# Driver para inserir uma lista do BsonDocument
tipo. Cada documento contém:
Um campo
text
que contém o resumo do filme.Um campo
embedding
que contém a array de flutuações a partir da geração das incorporações vetoriais.
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(); } }
Atualize o Program.cs
em seu projeto.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas.
Especificamente, este código utiliza a função GetEmbeddingsAsync
que você definiu para gerar incorporações a partir de uma matriz de textos de exemplo e inseri-los na coleção sample_db.embeddings
no Atlas.
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);
Compile e execute seu projeto.
dotnet run MyCompany.Embeddings.csproj
Successfully inserted 3 documents into Atlas
Você também pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção sample_db.embeddings
no seu cluster.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Defina uma DataService
classe .
Crie uma nova classe em um arquivo do mesmo nome denominado DataService.cs
e cole o seguinte código. Este código cria duas funções que fazem o seguinte:
Conecte-se ao seu cluster do Atlas.
O método
GetDocuments
obtém um subconjunto de documentos da collectionsample_airbnb.listingsAndReviews
que possuem um camposummary
não vazio.A tarefa assíncrona
AddEmbeddings
cria um novo campoembeddings
em documentos na collectionsample_airbnb.listingsAndReviews
cujo_id
corresponde a um dos documentos recuperados no métodoGetDocuments
.
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; } }
Atualize o Program.cs
em seu projeto.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas.
Especificamente, este código utiliza a função GetEmbeddingsAsync
que você definiu para gerar incorporações a partir de uma matriz de textos de exemplo e inseri-los na coleção sample_db.embeddings
no Atlas.
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"); }
Crie um arquivo chamado create-embeddings.go
e cole o código a seguir.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas.
Especificamente, este código usa a função GetEmbeddings
que você definiu e o driver do MongoDB Go para gerar incorporações a partir de uma array de textos de amostra e ingeri-los na coleção sample_db.embeddings
no Atlas.
package main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var data = []string{ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", } type TextWithEmbedding struct { Text string Embedding []float32 } func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") embeddings := common.GetEmbeddings(data) docsToInsert := make([]interface{}, len(embeddings)) for i, string := range data { docsToInsert[i] = TextWithEmbedding{ Text: string, Embedding: embeddings[i], } } result, err := coll.InsertMany(ctx, docsToInsert) if err != nil { log.Fatalf("failed to insert documents: %v", err) } fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs)) }
package main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var data = []string{ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", } type TextWithEmbedding struct { Text string Embedding []float64 } func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") embeddings := common.GetEmbeddings(data) docsToInsert := make([]interface{}, len(data)) for i, movie := range data { docsToInsert[i] = TextWithEmbedding{ Text: movie, Embedding: embeddings[i], } } result, err := coll.InsertMany(ctx, docsToInsert) if err != nil { log.Fatalf("failed to insert documents: %v", err) } fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs)) }
Salve e execute o arquivo.
go run create-embeddings.go
Successfully inserted 3 documents into Atlas
go run create-embeddings.go
Successfully inserted 3 documents into Atlas
Você também pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção sample_db.embeddings
no seu cluster.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Crie um arquivo chamado create-embeddings.go
e cole o código a seguir.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas. Especificamente, esse código faz o seguinte:
Conecta-se ao seu cluster do Atlas.
Obtém um subconjunto de documentos da coleção
sample_airbnb.listingsAndReviews
que tem um camposummary
não vazio.Gera incorporações do campo
summary
de cada documento usando a funçãoGetEmbeddings
que você definiu.Atualiza cada documento com um novo campo
embeddings
que contém o valor de incorporação usando o Go Driver do MongoDB.
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) }
Crie um arquivo que contenha modelos Go para a coleção.
Para simplificar a ordenação e a desordenação de objetos Go de e para o BSON, crie um arquivo que contenha modelos para os documentos nesta coleção.
Mover para o diretório
common
.cd common Crie um arquivo denominado
models.go
e cole o seguinte código nele:models.gopackage common import ( "time" "go.mongodb.org/mongo-driver/bson/primitive" ) type Image struct { ThumbnailURL string `bson:"thumbnail_url"` MediumURL string `bson:"medium_url"` PictureURL string `bson:"picture_url"` XLPictureURL string `bson:"xl_picture_url"` } type Host struct { ID string `bson:"host_id"` URL string `bson:"host_url"` Name string `bson:"host_name"` Location string `bson:"host_location"` About string `bson:"host_about"` ThumbnailURL string `bson:"host_thumbnail_url"` PictureURL string `bson:"host_picture_url"` Neighborhood string `bson:"host_neighborhood"` IsSuperhost bool `bson:"host_is_superhost"` HasProfilePic bool `bson:"host_has_profile_pic"` IdentityVerified bool `bson:"host_identity_verified"` ListingsCount int32 `bson:"host_listings_count"` TotalListingsCount int32 `bson:"host_total_listings_count"` Verifications []string `bson:"host_verifications"` } type Location struct { Type string `bson:"type"` Coordinates []float64 `bson:"coordinates"` IsLocationExact bool `bson:"is_location_exact"` } type Address struct { Street string `bson:"street"` Suburb string `bson:"suburb"` GovernmentArea string `bson:"government_area"` Market string `bson:"market"` Country string `bson:"Country"` CountryCode string `bson:"country_code"` Location Location `bson:"location"` } type Availability struct { Thirty int32 `bson:"availability_30"` Sixty int32 `bson:"availability_60"` Ninety int32 `bson:"availability_90"` ThreeSixtyFive int32 `bson:"availability_365"` } type ReviewScores struct { Accuracy int32 `bson:"review_scores_accuracy"` Cleanliness int32 `bson:"review_scores_cleanliness"` CheckIn int32 `bson:"review_scores_checkin"` Communication int32 `bson:"review_scores_communication"` Location int32 `bson:"review_scores_location"` Value int32 `bson:"review_scores_value"` Rating int32 `bson:"review_scores_rating"` } type Review struct { ID string `bson:"_id"` Date time.Time `bson:"date,omitempty"` ListingId string `bson:"listing_id"` ReviewerId string `bson:"reviewer_id"` ReviewerName string `bson:"reviewer_name"` Comments string `bson:"comments"` } type Listing struct { ID string `bson:"_id"` ListingURL string `bson:"listing_url"` Name string `bson:"name"` Summary string `bson:"summary"` Space string `bson:"space"` Description string `bson:"description"` NeighborhoodOverview string `bson:"neighborhood_overview"` Notes string `bson:"notes"` Transit string `bson:"transit"` Access string `bson:"access"` Interaction string `bson:"interaction"` HouseRules string `bson:"house_rules"` PropertyType string `bson:"property_type"` RoomType string `bson:"room_type"` BedType string `bson:"bed_type"` MinimumNights string `bson:"minimum_nights"` MaximumNights string `bson:"maximum_nights"` CancellationPolicy string `bson:"cancellation_policy"` LastScraped time.Time `bson:"last_scraped,omitempty"` CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"` FirstReview time.Time `bson:"first_review,omitempty"` LastReview time.Time `bson:"last_review,omitempty"` Accommodates int32 `bson:"accommodates"` Bedrooms int32 `bson:"bedrooms"` Beds int32 `bson:"beds"` NumberOfReviews int32 `bson:"number_of_reviews"` Bathrooms primitive.Decimal128 `bson:"bathrooms"` Amenities []string `bson:"amenities"` Price primitive.Decimal128 `bson:"price"` WeeklyPrice primitive.Decimal128 `bson:"weekly_price"` MonthlyPrice primitive.Decimal128 `bson:"monthly_price"` CleaningFee primitive.Decimal128 `bson:"cleaning_fee"` ExtraPeople primitive.Decimal128 `bson:"extra_people"` GuestsIncluded primitive.Decimal128 `bson:"guests_included"` Image Image `bson:"images"` Host Host `bson:"host"` Address Address `bson:"address"` Availability Availability `bson:"availability"` ReviewScores ReviewScores `bson:"review_scores"` Reviews []Review `bson:"reviews"` Embeddings []float32 `bson:"embeddings,omitempty"` } models.gopackage common import ( "time" "go.mongodb.org/mongo-driver/bson/primitive" ) type Image struct { ThumbnailURL string `bson:"thumbnail_url"` MediumURL string `bson:"medium_url"` PictureURL string `bson:"picture_url"` XLPictureURL string `bson:"xl_picture_url"` } type Host struct { ID string `bson:"host_id"` URL string `bson:"host_url"` Name string `bson:"host_name"` Location string `bson:"host_location"` About string `bson:"host_about"` ThumbnailURL string `bson:"host_thumbnail_url"` PictureURL string `bson:"host_picture_url"` Neighborhood string `bson:"host_neighborhood"` IsSuperhost bool `bson:"host_is_superhost"` HasProfilePic bool `bson:"host_has_profile_pic"` IdentityVerified bool `bson:"host_identity_verified"` ListingsCount int32 `bson:"host_listings_count"` TotalListingsCount int32 `bson:"host_total_listings_count"` Verifications []string `bson:"host_verifications"` } type Location struct { Type string `bson:"type"` Coordinates []float64 `bson:"coordinates"` IsLocationExact bool `bson:"is_location_exact"` } type Address struct { Street string `bson:"street"` Suburb string `bson:"suburb"` GovernmentArea string `bson:"government_area"` Market string `bson:"market"` Country string `bson:"Country"` CountryCode string `bson:"country_code"` Location Location `bson:"location"` } type Availability struct { Thirty int32 `bson:"availability_30"` Sixty int32 `bson:"availability_60"` Ninety int32 `bson:"availability_90"` ThreeSixtyFive int32 `bson:"availability_365"` } type ReviewScores struct { Accuracy int32 `bson:"review_scores_accuracy"` Cleanliness int32 `bson:"review_scores_cleanliness"` CheckIn int32 `bson:"review_scores_checkin"` Communication int32 `bson:"review_scores_communication"` Location int32 `bson:"review_scores_location"` Value int32 `bson:"review_scores_value"` Rating int32 `bson:"review_scores_rating"` } type Review struct { ID string `bson:"_id"` Date time.Time `bson:"date,omitempty"` ListingId string `bson:"listing_id"` ReviewerId string `bson:"reviewer_id"` ReviewerName string `bson:"reviewer_name"` Comments string `bson:"comments"` } type Listing struct { ID string `bson:"_id"` ListingURL string `bson:"listing_url"` Name string `bson:"name"` Summary string `bson:"summary"` Space string `bson:"space"` Description string `bson:"description"` NeighborhoodOverview string `bson:"neighborhood_overview"` Notes string `bson:"notes"` Transit string `bson:"transit"` Access string `bson:"access"` Interaction string `bson:"interaction"` HouseRules string `bson:"house_rules"` PropertyType string `bson:"property_type"` RoomType string `bson:"room_type"` BedType string `bson:"bed_type"` MinimumNights string `bson:"minimum_nights"` MaximumNights string `bson:"maximum_nights"` CancellationPolicy string `bson:"cancellation_policy"` LastScraped time.Time `bson:"last_scraped,omitempty"` CalendarLastScraped time.Time `bson:"calendar_last_scraped,omitempty"` FirstReview time.Time `bson:"first_review,omitempty"` LastReview time.Time `bson:"last_review,omitempty"` Accommodates int32 `bson:"accommodates"` Bedrooms int32 `bson:"bedrooms"` Beds int32 `bson:"beds"` NumberOfReviews int32 `bson:"number_of_reviews"` Bathrooms primitive.Decimal128 `bson:"bathrooms"` Amenities []string `bson:"amenities"` Price primitive.Decimal128 `bson:"price"` WeeklyPrice primitive.Decimal128 `bson:"weekly_price"` MonthlyPrice primitive.Decimal128 `bson:"monthly_price"` CleaningFee primitive.Decimal128 `bson:"cleaning_fee"` ExtraPeople primitive.Decimal128 `bson:"extra_people"` GuestsIncluded primitive.Decimal128 `bson:"guests_included"` Image Image `bson:"images"` Host Host `bson:"host"` Address Address `bson:"address"` Availability Availability `bson:"availability"` ReviewScores ReviewScores `bson:"review_scores"` Reviews []Review `bson:"reviews"` Embeddings []float64 `bson:"embeddings,omitempty"` } Volte para o diretório raiz do projeto .
cd ../
Gerar incorporações.
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
Você pode visualizar suas incorporações vetoriais conforme são geradas navegando até a coleção sample_airbnb.listingsAndReviews
na IU do Atlas.
Defina o código para gerar incorporações a partir de uma coleção existente no Atlas.
Crie um arquivo denominado CreateEmbeddings.java
e cole o seguinte código.
Este código utiliza o getEmbeddings
método e o MongoDB Java Sync Driver para fazer o seguinte:
Conecte-se ao seu cluster do Atlas.
Obtenha a array de textos de exemplo.
Gere incorporações de cada texto utilizando o método
getEmbeddings
que você definiu anteriormente.Gerencie as incorporações na coleção
sample_db.embeddings
no Atlas.
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); } } }
Gere as incorporações.
Salve e execute o arquivo. A saída se assemelha a:
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}]
Você também pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção sample_db.embeddings
no seu cluster.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Defina o código para gerar incorporações a partir de uma coleção existente no Atlas.
Crie um arquivo denominado CreateEmbeddings.java
e cole o seguinte código.
Este código utiliza o getEmbeddings
método e o MongoDB Java Sync Driver para fazer o seguinte:
Conecte-se ao seu cluster do Atlas.
Obtenha um subconjunto de documentos da coleção
sample_airbnb.listingsAndReviews
que possuem um camposummary
não vazio.Gere incorporações a partir do campo
summary
de cada documento usando o métodogetEmbeddings
definido anteriormente.Atualize cada documento com um novo campo
embeddings
que contém o valor de incorporação.
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); } } }
Gere as incorporações.
Salve e execute o arquivo. A saída se assemelha a:
Generating embeddings for 50 documents. This operation may take up to several minutes. Added embeddings successfully to 50 documents.
Você também pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção sample_airbnb.listingsAndReviews
no seu cluster.
Crie um arquivo chamado create-embeddings.js
e cole o código a seguir.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas.
Especificamente, este código usa a função getEmbedding
que você definiu e o driver do MongoDB Node.js para gerar incorporações a partir de uma array de textos de amostra e ingeri-los na coleção sample_db.embeddings
no Atlas.
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);
Salve e execute o arquivo.
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, ... ]
Observação
O número de dimensões na saída foi truncado para legibilidade.
Você também pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção sample_db.embeddings
no seu cluster.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Crie um arquivo chamado create-embeddings.js
e cole o código a seguir.
Use o código a seguir para gerar incorporações a partir de uma coleção existente no Atlas. Especificamente, esse código faz o seguinte:
Conecta-se ao seu cluster do Atlas.
Obtém um subconjunto de documentos da coleção
sample_airbnb.listingsAndReviews
que tem um camposummary
não vazio.Gera incorporações do campo
summary
de cada documento usando a funçãogetEmbedding
que você definiu.Atualiza cada documento com um novo campo
embedding
que contém o valor de incorporação usando o driver Node.js do MongoDB.
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);
Salve e execute o arquivo.
node --env-file=.env create-embeddings.js
Generating embeddings for documents... Count of documents updated: 50
Você pode visualizar suas incorporações vetoriais conforme elas são geradas navegando até a sample_airbnb.listingsAndReviews
coleção na interface do usuário do Atlas e expandindo os campos em um documento.
(Condicional) Define as funções para gerar incorporações BSON.
Se você ainda não carregou as get_embedding
generate_bson_vector
funções, e em create_docs_with_bson_vector_embeddings
seu bloco de anotações, consulte Definir uma função de incorporação para carregar essas funções em seu bloco de anotações.
Carregue os dados de amostra.
Cole e execute o seguinte código no seu notebook:
# Sample data sentences = [ "Titanic: The story of the 1912 sinking of the largest luxury liner ever built", "The Lion King: Lion cub and future king Simba searches for his identity", "Avatar: A marine is dispatched to the moon Pandora on a unique mission", "Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious.", "The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son.", "Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life.", "Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.", "The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers.", "Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire.", "The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.", "Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past.", "The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy.", "Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love.", "The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer.", "E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home.", "Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action.", "Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family.", "Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion.", "Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude.", "Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory." ]
Gere as incorporações para seus dados.
Use o código a seguir para gerar incorporações a partir de novos dados.
Especificamente, este código utiliza a get_embedding
função que você definiu e o Driver PyMongo para gerar incorporações a partir de uma matriz de textos de exemplo.
import pymongo from sentence_transformers.quantization import quantize_embeddings float32_embeddings = get_embedding(sentences, precision="float32") int8_embeddings = get_embedding(sentences, precision="int8") int1_embeddings = get_embedding(sentences, precision="ubinary") # Print stored embeddings print("Generated embeddings stored in different variables:") for i, text in enumerate(sentences): print(f"\nText: {text}") print(f"Float32 Embedding: {float32_embeddings[i][:3]}... (truncated)") print(f"Int8 Embedding: {int8_embeddings[i][:3]}... (truncated)") print(f"Ubinary Embedding: {int1_embeddings[i][:3]}... (truncated)")
Generated embeddings stored in different variables: Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Float32 Embedding: [-0.01089042 0.05926645 -0.00291325]... (truncated) Int8 Embedding: [-15 127 56]... (truncated) Ubinary Embedding: [ 77 30 209]... (truncated) Text: The Lion King: Lion cub and future king Simba searches for his identity Float32 Embedding: [-0.05607051 -0.01360618 0.00523855]... (truncated) Int8 Embedding: [-128 -109 110]... (truncated) Ubinary Embedding: [ 37 18 151]... (truncated) Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Float32 Embedding: [-0.0275258 0.01144342 -0.02360895]... (truncated) Int8 Embedding: [-57 -28 -79]... (truncated) Ubinary Embedding: [ 76 16 144]... (truncated) Text: Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious. Float32 Embedding: [-0.01759741 0.03254957 -0.02090798]... (truncated) Int8 Embedding: [-32 40 -61]... (truncated) Ubinary Embedding: [ 77 27 176]... (truncated) Text: The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son. Float32 Embedding: [ 0.00503172 0.04311579 -0.00074904]... (truncated) Int8 Embedding: [23 74 70]... (truncated) Ubinary Embedding: [215 26 145]... (truncated) Text: Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life. Float32 Embedding: [0.02349479 0.05669326 0.00458773]... (truncated) Int8 Embedding: [ 69 118 105]... (truncated) Ubinary Embedding: [237 154 159]... (truncated) Text: Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry. Float32 Embedding: [-0.03294644 0.02671233 -0.01864981]... (truncated) Int8 Embedding: [-70 21 -47]... (truncated) Ubinary Embedding: [ 77 90 146]... (truncated) Text: The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers. Float32 Embedding: [-0.02489671 0.02847196 -0.00290637]... (truncated) Int8 Embedding: [-50 27 56]... (truncated) Ubinary Embedding: [ 95 154 129]... (truncated) Text: Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire. Float32 Embedding: [-0.01235448 0.01524397 -0.01063425]... (truncated) Int8 Embedding: [-19 -15 5]... (truncated) Ubinary Embedding: [ 68 26 210]... (truncated) Text: The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover. Float32 Embedding: [ 0.04665203 0.01392298 -0.01743002]... (truncated) Int8 Embedding: [127 -20 -39]... (truncated) Ubinary Embedding: [207 88 208]... (truncated) Text: Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past. Float32 Embedding: [0.00929601 0.04206405 0.00701248]... (truncated) Int8 Embedding: [ 34 71 121]... (truncated) Ubinary Embedding: [228 90 130]... (truncated) Text: The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy. Float32 Embedding: [-0.01451324 -0.00897367 0.0077793 ]... (truncated) Int8 Embedding: [-24 -94 127]... (truncated) Ubinary Embedding: [ 57 150 32]... (truncated) Text: Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love. Float32 Embedding: [-0.01458643 0.03639758 -0.02587282]... (truncated) Int8 Embedding: [-25 52 -94]... (truncated) Ubinary Embedding: [ 78 218 216]... (truncated) Text: The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer. Float32 Embedding: [-0.00205381 -0.00039482 -0.01630799]... (truncated) Int8 Embedding: [ 6 -66 -31]... (truncated) Ubinary Embedding: [ 9 82 154]... (truncated) Text: E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home. Float32 Embedding: [ 0.01105334 0.00776658 -0.03092942]... (truncated) Int8 Embedding: [ 38 -40 -128]... (truncated) Ubinary Embedding: [205 24 146]... (truncated) Text: Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. Float32 Embedding: [ 0.00266668 -0.01926583 -0.00727963]... (truncated) Int8 Embedding: [ 17 -128 27]... (truncated) Ubinary Embedding: [148 82 194]... (truncated) Text: Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family. Float32 Embedding: [-0.00031873 -0.01352339 -0.02882693]... (truncated) Int8 Embedding: [ 10 -109 -114]... (truncated) Ubinary Embedding: [ 12 26 144]... (truncated) Text: Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion. Float32 Embedding: [ 0.00957429 0.01855557 -0.02353773]... (truncated) Int8 Embedding: [ 34 -5 -79]... (truncated) Ubinary Embedding: [212 18 144]... (truncated) Text: Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude. Float32 Embedding: [-0.01787405 0.03672816 -0.00972007]... (truncated) Int8 Embedding: [-33 53 11]... (truncated) Ubinary Embedding: [ 68 154 145]... (truncated) Text: Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory. Float32 Embedding: [-0.03515214 -0.00503571 0.00183181]... (truncated) Int8 Embedding: [-76 -81 87]... (truncated) Ubinary Embedding: [ 35 222 152]... (truncated)
Gere os vetores BSON a partir das suas incorporações.
Use o código a seguir para converter as incorporações vetoriais geradas em vetores BSON. O código usa o driver PyMongo.
Especificamente, este código converte as incorporações geradas em tipos float32
, int8
e int1
compactados e, em seguida, quantiza os vetores float32
, int8
e int1
.
from bson.binary import Binary, BinaryVectorDtype bson_float32_embeddings = [] bson_int8_embeddings = [] bson_int1_embeddings = [] # Convert each embedding to BSON for (f32_emb, int8_emb, int1_emb) in zip(float32_embeddings, int8_embeddings, int1_embeddings): bson_float32_embeddings.append(generate_bson_vector(f32_emb, BinaryVectorDtype.FLOAT32)) bson_int8_embeddings.append(generate_bson_vector(int8_emb, BinaryVectorDtype.INT8)) bson_int1_embeddings.append(generate_bson_vector(int1_emb, BinaryVectorDtype.PACKED_BIT)) # Print the embeddings for idx, text in enumerate(sentences): print(f"\nText: {text}") print(f"Float32 BSON: {bson_float32_embeddings[idx]}") print(f"Int8 BSON: {bson_int8_embeddings[idx]}") print(f"Int1 BSON: {bson_int1_embeddings[idx]}")
Text: Titanic: The story of the 1912 sinking of the largest luxury liner ever built Float32 BSON: b'\'\x00\xbam2\xbc`\xc1r=7\xec>\xbb\xe6\xf3\x...' Int8 BSON: b'\x03\x00\xf1\x7f8\xdf\xfeC\x1e>\xef\xd6\xf5\x9...' Int1 BSON: b'\x10\x00M\x1e\xd1\xd2\x05\xaeq\xdf\x9a\x1d\xbc...' Text: The Lion King: Lion cub and future king Simba searches for his identity Float32 BSON: b'\'\x001\xaae\xbdr\xec^\xbc"\xa8\xab;\x91\xd...' Int8 BSON: b'\x03\x00\x80\x93n\x06\x80\xca\xd3.\xa2\xe3\xd1...' Int1 BSON: b'\x10\x00%\x12\x97\xa6\x8f\xdf\x89\x9d2\xcb\x99...' Text: Avatar: A marine is dispatched to the moon Pandora on a unique mission Float32 BSON: b'\'\x00\xcc}\xe1\xbc-};<\x8eg\xc1\xbc\xcb\xd...' Int8 BSON: b'\x03\x00\xc7\xe4\xb1\xdf/\xe2\xd2\x90\xf7\x02|...' Int1 BSON: b'\x10\x00L\x10\x90\xb6\x0f\x8a\x91\xaf\x92|\xf9...' Text: Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious. Float32 BSON: b'\'\x00o(\x90\xbc\xb3R\x05=8G\xab\xbc\xfb\xc...' Int8 BSON: b'\x03\x00\xe0(\xc3\x10*\xda\xfe\x19\xbf&<\xd1\x...' Int1 BSON: b'\x10\x00M\x1b\xb0\x86\rn\x93\xaf:w\x9f}\x92\xd...' Text: The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son. Float32 BSON: b'\'\x00\x1d\xe1\xa4;0\x9a0=C[D\xba\xb5\xf2\x...' Int8 BSON: b'\x03\x00\x17JF2\xb9\xddZ8\xa1\x0c\xc6\x80\xd8$...' Int1 BSON: b'\x10\x00\xd7\x1a\x91\x87\x0e\xc9\x91\x8b\xba\x...' Text: Forrest Gump: A man with a low IQ recounts several decades of extraordinary events in his life. Float32 BSON: b'\'\x00#x\xc0<27h=\xb5T\x96;:\xc4\x9c\xbd\x1...' Int8 BSON: b'\x03\x00Evi\x80\x13\xd6\x1cCW\x80\x01\x9e\xe58...' Int1 BSON: b'\x10\x00\xed\x9a\x9f\x97\x1f.\x12\xf9\xba];\x7...' Text: Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry. Float32 BSON: b'\'\x00\xd9\xf2\x06\xbd\xd2\xd3\xda<\x7f\xc7...' Int8 BSON: b'\x03\x00\xba\x15\xd1-\x0c\x03\xe6\xea\rQ\x1f\x...' Int1 BSON: b'\x10\x00MZ\x92\xb7#\xaa\x99=\x9a\x99\x9c|<\xf8...' Text: The Matrix: A hacker discovers the true nature of reality and his role in the war against its controllers. Float32 BSON: b'\'\x00/\xf4\xcb\xbc\t>\xe9<\xc9x>\xbb\xcc\x...' Int8 BSON: b'\x03\x00\xce\x1b815\xcf1\xc6s\xe5\n\xe4\x192G\...' Int1 BSON: b'\x10\x00_\x9a\x81\xa6\x0f\x0f\x93o2\xd8\xfe|\x...' Text: Star Wars: A young farm boy is swept into the struggle between the Rebel Alliance and the Galactic Empire. Float32 BSON: b'\'\x00sjJ\xbc\xd6\xc1y<I;.\xbc\xb1\x80\t\xb...' Int8 BSON: b'\x03\x00\xed\xf1\x05\xe2\xc7\xfa\xd4\xab5\xeb\...' Int1 BSON: b'\x10\x00D\x1a\xd2\x86\x0ey\x92\x8f\xaa\x89\x1c...' Text: The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover. Float32 BSON: b'\'\x004\x16?=9\x1dd<g\xc9\x8e\xbc\xdf\x81\x...' Int8 BSON: b'\x03\x00\x7f\xec\xd9\xdc)\xd6)\x05\x18\x7f\xa6...' Int1 BSON: b"\x10\x00\xcfX\xd0\xb7\x0e\xcf\xd9\r\xf0U\xb4]6..." Text: Indiana Jones and the Last Crusade: An archaeologist pursues the Holy Grail while confronting adversaries from the past. Float32 BSON: b'\'\x00HN\x18<ZK,=\xf9\xc8\xe5;\x9e\xed\xa0\...' Int8 BSON: b'\x03\x00"Gy\x01\xeb\xec\xfc\x80\xe4a\x7f\x88\x...' Int1 BSON: b'\x10\x00\xe4Z\x82\xb6\xad\xec\x10-\x9a\x99;?j\...' Text: The Dark Knight: Batman faces a new menace, the Joker, who plunges Gotham into anarchy. Float32 BSON: b'\'\x00\xef\xc8m\xbcJ\x06\x13\xbcv\xe9\xfe;...' Int8 BSON: b'\x03\x00\xe8\xa2\x7fIE\xba\x9f\xfaT2\xf1\xc1\...' Int1 BSON: b'\x10\x009\x96 \xb7\x8e\xc9\x81\xaf\xaa\x9f\xa...' Text: Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love. Float32 BSON: b'\'\x00\xee\xfbn\xbc\xa0\x15\x15=<\xf3\xd3x...' Int8 BSON: b'\x03\x00\xe74\xa2\xe5\x15\x165\xb9dM8C\xd7E\x...' Int1 BSON: b'\x10\x00N\xda\xd8\xb6\x03N\x98\xbd\xdaY\x1b| ...' Text: The Silence of the Lambs: A young FBI agent seeks the help of an incarcerated cannibalistic killer to catch another serial killer. Float32 BSON: b'\'\x002\x99\x06\xbb\x82\x00\xcf\xb9X\x98\x...' Int8 BSON: b'\x03\x00\x06\xbe\xe1.\x7f\x80\x04C\xd7e\x80\x...' Int1 BSON: b'\x10\x00\tR\x9a\xd6\x0c\xb1\x9a\xbc\x90\xf5\x...' Text: E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home. Float32 BSON: b'\'\x00\x14\x195<\xd4~\xfe;\xb3_\xfd\xbc \xe...' Int8 BSON: b'\x03\x00&\xd8\x80\x92\x01\x7f\xbfF\xd4\x10\xf0...' Int1 BSON: b'\x10\x00\xcd\x18\x92\x92\x8dJ\x92\xbd\x9a\xd3\...' Text: Saving Private Ryan: During WWII, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. Float32 BSON: b'\'\x00\x8a\xc3.;_\xd3\x9d\xbc\xf2\x89\xee\x...' Int8 BSON: b'\x03\x00\x11\x80\x1b5\xe9\x19\x80\x8f\xb1N\xda...' Int1 BSON: b"\x10\x00\x94R\xc2\xd2\x0f\xfa\x90\xbc\xd8\xd6\...' Text: Gladiator: A once-powerful Roman general seeks vengeance against the corrupt emperor who betrayed his family. Float32 BSON: b'\'\x00\xe6\x1a\xa7\xb94\x91]\xbcs&\xec\xbc\...' Int8 BSON: b'\x03\x00\n\x93\x8e,n\xce\xe8\x9b@\x00\xf9\x7f\...' Int1 BSON: b'\x10\x00\x0c\x1a\x90\x97\x0f\x19\x80/\xba\x98\...' Text: Rocky: A small-time boxer gets a once-in-a-lifetime chance to fight the world heavyweight champion. Float32 BSON: b'\'\x00\x7f\xdd\x1c<\xd9\x01\x98<1\xd2\xc0\xb...' Int8 BSON: b'\x03\x00"\xfb\xb1\x7f\xd3\xd6\x04\xbe\x80\xf9L\...' Int1 BSON: b'\x10\x00\xd4\x12\x90\xa6\x8by\x99\x8d\xa2\xbd\x...' Text: Pirates of the Caribbean: Jack Sparrow races to recover the heart of Davy Jones to escape eternal servitude. Float32 BSON: b'\'\x00\x98l\x92\xbcDp\x16=\xf0@\x1f\xbc\xd0\...' Int8 BSON: b'\x03\x00\xdf5\x0b\xe3\xbf\xe5\xa5\xad\x7f\x02\x...' Int1 BSON: b'\x10\x00D\x9a\x91\x96\x07\xfa\x93\x8d\xb2D\x92]...' Text: Schindler's List: The true story of a man who saved hundreds of Jews during the Holocaust by employing them in his factory. Float32 BSON: b'\'\x00\xb0\xfb\x0f\xbd\x9b\x02\xa5\xbbZ\x19\...' Int8 BSON: b'\x03\x00\xb4\xafW\xd9\xd7\xc3\x7f~QM\x86\x83\xf...' Int1 BSON: b'\x10\x00#\xde\x98\x96\x0e\xcc\x12\xf6\xbb\xdd2}...'
Crie documentos com incorporações vetoriais BSON.
Use o código a seguir para criar documentos com as incorporações vetoriais BSON. O código utiliza a create_docs_with_bson_vector_embeddings
função para criar os documentos.
# Create BSON documents docs = create_docs_with_bson_vector_embeddings(bson_float32_embeddings, bson_int8_embeddings, bson_int1_embeddings, sentences)
Conecte-se ao seu Atlas cluster para carregar os dados.
Cole o código a seguir em seu bloco de anotações, substitua o <connection-string>
pela string de conexão SRVdo Atlas cluster e execute o código.
Observação
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_db"] collection = db["embeddings"] # Ingest data into Atlas collection.insert_many(docs)
InsertManyResult([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], acknowledged=True)
Você pode verificar suas incorporações vetoriais visualizando-as na interface do Atlas dentro do sample_db.embeddings
namespace em seu cluster.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Cole o código a seguir no seu notebook.
Use o código a seguir para gerar incorporações a partir de novos dados.
Em especial, este código usa a função get_embedding
que você definiu e o driver do MongoDB PyMongo para gerar incorporações a partir de uma array de textos de amostra e ingeri-los na coleção 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.
Especifique a string de conexão.
Substitua <connection-string>
pela string de conexão SRV do seu cluster do Atlas.
Observação
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Execute o código.
Você pode verificar as incorporações vetoriais visualizando-os na IU do Atlas navegando até a coleção sample_db.embeddings
em seu cluster.
(Condicional) Define as funções para gerar incorporações BSON.
Se você ainda não carregou as get_embedding
funções e generate_bson_vector
em seu bloco de anotações, consulte Definir uma função de incorporação para carregar estas funções em seu bloco de anotações.
Carregue seus dados existentes.
Buscar os dados do seu agrupamento do Atlas e carregue-os no bloco de anotações. O seguinte código obtém o campo summary
de 50
documentos na coleção sample_airbnb.listingAndReviews
.
import pymongo # Connect to your Atlas cluster mongo_client = pymongo.MongoClient("<connection-string>") db = mongo_client["sample_airbnb"] collection = db["listingsAndReviews"] # Define a filter to exclude documents with null or empty 'summary' fields summary_filter = {"summary": {"$nin": [None, ""]}} # Get a subset of documents in the collection documents = collection.find(summary_filter, {'_id': 1, 'summary': 1}).limit(50)
Gere, converta e ingira as incorporações no seu cluster do Atlas .
O código a seguir primeiro float32
gera, int8
e int1
incorporações para os dados e, em seguida, converte as incorporações float32
emint8
int1
subtipos BSON, e e, finalmente, carrega as incorporações no Atlas cluster.
Observação
Pode levar alguns minutos para que a operação seja concluída.
import pymongo from bson.binary import Binary updated_doc_count = 0 for doc in documents: summary = doc["summary"] # Generate float32 and other embeddings float32_embeddings = get_embedding(summary, precision="float32") int8_embeddings = get_embedding(summary, precision="int8") int1_embeddings = get_embedding(summary, precision="ubinary") # Initialize variables to store BSON vectors bson_float32_embeddings = generate_bson_vector(float32_embeddings, BinaryVectorDtype.FLOAT32) bson_int8_embeddings = generate_bson_vector(int8_embeddings, BinaryVectorDtype.INT8) bson_int1_embeddings = generate_bson_vector(int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Update each document with new embedding fields collection.update_one( {"_id": doc["_id"]}, {"$set": { "BSON-Float32-Embedding": bson_float32_embeddings, "BSON-Int8-Embedding": bson_int8_embeddings, "BSON-Int1-Embedding": bson_int1_embeddings }}, ) updated_doc_count += 1 print(f"Updated {updated_doc_count} documents.")
Updated 50 documents.
Observação
Este exemplo usa a coleção sample_airbnb.listingsAndReviews
de nossos dados de amostra, mas você pode adaptar o código para funcionar com qualquer coleção em seu cluster.
Cole o código a seguir no seu notebook.
Use o código a seguir para gerar inserções de um campo em uma coleção existente. Especificamente, esse código faz o seguinte:
Conecta-se ao seu cluster do Atlas.
Obtém um subconjunto de documentos da coleção
sample_airbnb.listingsAndReviews
que tem um camposummary
não vazio.Gera incorporações do campo
summary
de cada documento usando a funçãoget_embedding
que você definiu.Atualiza cada documento com um novo campo
embedding
que contém o valor de incorporação usando o MongoDB PyMongo Driver.
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.
Especifique a string de conexão.
Substitua <connection-string>
pela string de conexão SRV do seu cluster do Atlas.
Observação
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Execute o código.
Você pode visualizar suas incorporações vetoriais conforme elas são geradas navegando até a sample_airbnb.listingsAndReviews
coleção na interface do usuário do Atlas e expandindo os campos em um documento.
Criar incorporações para queries
Nesta seção, você indexa as incorporações vetoriais na sua coleção e cria uma incorporação que é usada para executar uma query de pesquisa de vetor de amostra.
Quando você executa a query, o Atlas Vector Search retorna documentos cujas incorporações estão mais próximas da incorporação de sua query de pesquisa vetorial. Isso indica que eles são semelhantes em significado.
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_db.embeddings
que especifica o campo embedding
como o tipo de vetor e a medida de similaridade como dotProduct
.
Cole o seguinte código para adicionar uma função
CreateVectorIndex
à sua classeDataService
noDataService.cs
.DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_db"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("embeddings"); public async Task AddDocumentsAsync(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { try { var searchIndexView = Collection.SearchIndexes; var name = "vector_index"; var type = SearchIndexType.VectorSearch; var definition = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "type", "vector" }, { "path", "embedding" }, { "numDimensions", <dimensions> }, { "similarity", "dotProduct" } } } } }; var model = new CreateSearchIndexModel(name, type, definition); searchIndexView.CreateOne(model); Console.WriteLine($"New search index named {name} is building."); // Polling for index status Console.WriteLine("Polling to check if the index is ready. This may take up to a minute."); bool queryable = false; while (!queryable) { var indexes = searchIndexView.List(); foreach (var index in indexes.ToEnumerable()) { if (index["name"] == name) { queryable = index["queryable"].AsBoolean; } } if (!queryable) { Thread.Sleep(5000); } } Console.WriteLine($"{name} is ready for querying."); } catch (Exception e) { Console.WriteLine($"Exception: {e.Message}"); } } } Substitua o valor do espaço reservado
<dimensions>
por1024
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Atualize o código no seu
Program.cs
.Remova o código que preencheu os documentos iniciais e substitua-o pelo seguinte código para criar o índice:
Program.csusing MyCompany.Embeddings; var dataService = new DataService(); dataService.CreateVectorIndex(); Salve o arquivo e, em seguida, compile e execute seu projeto para criar o índice:
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.
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Cole o seguinte código para adicionar uma função
PerformVectorQuery
à sua classeDataService
noDataService.cs
.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_db"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("embeddings"); public async Task AddDocumentsAsync(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { // Method details... } public List<BsonDocument>? PerformVectorQuery(float[] vector) { var vectorSearchStage = new BsonDocument { { "$vectorSearch", new BsonDocument { { "index", "vector_index" }, { "path", "embedding" }, { "queryVector", new BsonArray(vector) }, { "exact", true }, { "limit", 5 } } } }; var projectStage = new BsonDocument { { "$project", new BsonDocument { { "_id", 0 }, { "text", 1 }, { "score", new BsonDocument { { "$meta", "vectorSearchScore"} } } } } }; var pipeline = new[] { vectorSearchStage, projectStage }; return Collection.Aggregate<BsonDocument>(pipeline).ToList(); } } Atualize o código no seu
Program.cs
.Remova o código que criou o índice do vetor e adicione o código para executar uma query:
Program.csusing MongoDB.Bson; using MyCompany.Embeddings; var aiService = new AIService(); var queryString = "ocean tragedy"; var queryEmbedding = await aiService.GetEmbeddingsAsync([queryString]); if (!queryEmbedding.Any()) { Console.WriteLine("No embeddings found."); } else { var dataService = new DataService(); var matchingDocuments = dataService.PerformVectorQuery(queryEmbedding[queryString]); if (matchingDocuments == null) { Console.WriteLine("No documents matched the query."); } else { foreach (var document in matchingDocuments) { Console.WriteLine(document.ToJson()); } } } Salve o arquivo e, em seguida, compile e execute seu projeto para executar a query:
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 }
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_airbnb.listingsAndReviews
que especifica o campo embeddings
como o tipo de vetor e a medida de similaridade como euclidean
.
Cole o seguinte código para adicionar a função
CreateVectorIndex
à sua classeDataService
emDataService.cs
.DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_airbnb"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("listingsAndReviews"); public List<BsonDocument>? GetDocuments() { // Method details... } public async Task<long> AddEmbeddings(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { try { var searchIndexView = Collection.SearchIndexes; var name = "vector_index"; var type = SearchIndexType.VectorSearch; var definition = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "type", "vector" }, { "path", "embeddings" }, { "numDimensions", <dimensions> }, { "similarity", "dotProduct" } } } } }; var model = new CreateSearchIndexModel(name, type, definition); searchIndexView.CreateOne(model); Console.WriteLine($"New search index named {name} is building."); // Polling for index status Console.WriteLine("Polling to check if the index is ready. This may take up to a minute."); bool queryable = false; while (!queryable) { var indexes = searchIndexView.List(); foreach (var index in indexes.ToEnumerable()) { if (index["name"] == name) { queryable = index["queryable"].AsBoolean; } } if (!queryable) { Thread.Sleep(5000); } } Console.WriteLine($"{name} is ready for querying."); } catch (Exception e) { Console.WriteLine($"Exception: {e.Message}"); } } } Substitua o valor do espaço reservado
<dimensions>
por1024
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Atualize o código no seu
Program.cs
.Remova o código que adicionou incorporações aos documentos existentes e substitua-o pelo seguinte código para criar o índice:
Program.csusing MyCompany.Embeddings; var dataService = new DataService(); dataService.CreateVectorIndex(); Salve o arquivo e, em seguida, compile e execute seu projeto para criar o índice:
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.
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Cole o seguinte código para adicionar uma função
PerformVectorQuery
à sua classeDataService
noDataService.cs
.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
DataService.csnamespace MyCompany.Embeddings; using MongoDB.Driver; using MongoDB.Bson; public class DataService { private static readonly string? ConnectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); private static readonly MongoClient Client = new MongoClient(ConnectionString); private static readonly IMongoDatabase Database = Client.GetDatabase("sample_airbnb"); private static readonly IMongoCollection<BsonDocument> Collection = Database.GetCollection<BsonDocument>("listingsAndReviews"); public List<BsonDocument>? GetDocuments() { // Method details... } public async Task<long> AddEmbeddings(Dictionary<string, float[]> embeddings) { // Method details... } public void CreateVectorIndex() { // Method details... } public List<BsonDocument>? PerformVectorQuery(float[] vector) { var vectorSearchStage = new BsonDocument { { "$vectorSearch", new BsonDocument { { "index", "vector_index" }, { "path", "embeddings" }, { "queryVector", new BsonArray(vector) }, { "exact", true }, { "limit", 5 } } } }; var projectStage = new BsonDocument { { "$project", new BsonDocument { { "_id", 0 }, { "summary", 1 }, { "score", new BsonDocument { { "$meta", "vectorSearchScore"} } } } } }; var pipeline = new[] { vectorSearchStage, projectStage }; return Collection.Aggregate<BsonDocument>(pipeline).ToList(); } } Atualize o código no seu
Program.cs
.Remova o código que criou o índice do vetor e adicione o código para executar uma query:
Program.csusing MongoDB.Bson; using MyCompany.Embeddings; var aiService = new AIService(); var queryString = "beach house"; var queryEmbedding = await aiService.GetEmbeddingsAsync([queryString]); if (!queryEmbedding.Any()) { Console.WriteLine("No embeddings found."); } else { var dataService = new DataService(); var matchingDocuments = dataService.PerformVectorQuery(queryEmbedding[queryString]); if (matchingDocuments == null) { Console.WriteLine("No documents matched the query."); } else { foreach (var document in matchingDocuments) { Console.WriteLine(document.ToJson()); } } } Salve o arquivo e, em seguida, compile e execute seu projeto para executar a query:
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 }
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_db.embeddings
que especifica o campo embedding
como o tipo de vetor e a medida de similaridade como dotProduct
.
Crie um arquivo chamado
create-index.go
e cole o código a seguir.create-index.gopackage main import ( "context" "fmt" "log" "os" "time" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") indexName := "vector_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } indexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "embedding", NumDimensions: <dimensions>, Similarity: "dotProduct"}}, }, Options: opts, } log.Println("Creating the index.") searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("failed to create the search index: %v", err) } // Await the creation of the index. log.Println("Polling to confirm successful index creation.") searchIndexes := coll.SearchIndexes() var doc bson.Raw for doc == nil { cursor, err := searchIndexes.List(ctx, options.SearchIndexes().SetName(searchIndexName)) if err != nil { fmt.Errorf("failed to list search indexes: %w", err) } if !cursor.Next(ctx) { break } name := cursor.Current.Lookup("name").StringValue() queryable := cursor.Current.Lookup("queryable").Boolean() if name == searchIndexName && queryable { doc = cursor.Current } else { time.Sleep(5 * time.Second) } } log.Println("Name of Index Created: " + searchIndexName) } Substitua o valor do espaço reservado
<dimensions>
por1024
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Salve o arquivo e execute o seguinte comando:
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
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
vector-query.go
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type TextAndScore struct { Text string `bson:"text"` Score float32 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") query := "ocean tragedy" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embedding"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"text", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []TextAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score) } } vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type TextAndScore struct { Text string `bson:"text"` Score float64 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_db").Collection("embeddings") query := "ocean tragedy" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embedding"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"text", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []TextAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to TextAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Text: %v\nScore: %v\n", doc.Text, doc.Score) } } Salve o arquivo e execute o seguinte comando:
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
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_airbnb.listingsAndReviews
que especifica o campo embeddings
como o tipo de vetor e a medida de similaridade como euclidean
.
Crie um arquivo chamado
create-index.go
e cole o código a seguir.create-index.gopackage main import ( "context" "fmt" "log" "os" "time" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") indexName := "vector_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } indexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "embeddings", NumDimensions: <dimensions>, Similarity: "dotProduct", Quantization: "scalar"}}, }, Options: opts, } log.Println("Creating the index.") searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("failed to create the search index: %v", err) } // Await the creation of the index. log.Println("Polling to confirm successful index creation.") searchIndexes := coll.SearchIndexes() var doc bson.Raw for doc == nil { cursor, err := searchIndexes.List(ctx, options.SearchIndexes().SetName(searchIndexName)) if err != nil { fmt.Errorf("failed to list search indexes: %w", err) } if !cursor.Next(ctx) { break } name := cursor.Current.Lookup("name").StringValue() queryable := cursor.Current.Lookup("queryable").Boolean() if name == searchIndexName && queryable { doc = cursor.Current } else { time.Sleep(5 * time.Second) } } log.Println("Name of Index Created: " + searchIndexName) } Substitua o valor do espaço reservado
<dimensions>
por1024
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Salve o arquivo e execute o seguinte comando:
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
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
vector-query.go
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type SummaryAndScore struct { Summary string `bson:"summary"` Score float32 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") query := "beach house" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embeddings"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"summary", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []SummaryAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to SummaryAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Summary: %v\nScore: %v\n", doc.Summary, doc.Score) } } vector-query.gopackage main import ( "context" "fmt" "log" "my-embeddings-project/common" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type SummaryAndScore struct { Summary string `bson:"summary"` Score float64 `bson:"score"` } func main() { ctx := context.Background() // Connect to your Atlas cluster if err := godotenv.Load(); err != nil { log.Println("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("sample_airbnb").Collection("listingsAndReviews") query := "beach house" queryEmbedding := common.GetEmbeddings([]string{query}) pipeline := mongo.Pipeline{ bson.D{ {"$vectorSearch", bson.D{ {"queryVector", queryEmbedding[0]}, {"index", "vector_index"}, {"path", "embeddings"}, {"exact", true}, {"limit", 5}, }}, }, bson.D{ {"$project", bson.D{ {"_id", 0}, {"summary", 1}, {"score", bson.D{ {"$meta", "vectorSearchScore"}, }}, }}, }, } // Run the pipeline cursor, err := coll.Aggregate(ctx, pipeline) if err != nil { log.Fatalf("failed to run aggregation: %v", err) } defer func() { _ = cursor.Close(ctx) }() var matchingDocs []SummaryAndScore if err = cursor.All(ctx, &matchingDocs); err != nil { log.Fatalf("failed to unmarshal results to SummaryAndScore objects: %v", err) } for _, doc := range matchingDocs { fmt.Printf("Summary: %v\nScore: %v\n", doc.Summary, doc.Score) } } Salve o arquivo e execute o seguinte comando:
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
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_db.embeddings
que especifica o campo embedding
como o tipo de vetor e a medida de similaridade como dotProduct
.
Crie um arquivo chamado
CreateIndex.java
e cole o seguinte código:CreateIndex.javaimport com.mongodb.MongoException; import com.mongodb.client.ListSearchIndexesIterable; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.SearchIndexModel; import com.mongodb.client.model.SearchIndexType; import org.bson.Document; import org.bson.conversions.Bson; import java.util.Collections; import java.util.List; public class CreateIndex { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_db"); MongoCollection<Document> collection = database.getCollection("embeddings"); // define the index details String indexName = "vector_index"; int dimensionsHuggingFaceModel = 1024; int dimensionsOpenAiModel = 1536; Bson definition = new Document( "fields", Collections.singletonList( new Document("type", "vector") .append("path", "embedding") .append("numDimensions", <dimensions>) // replace with var for the model used .append("similarity", "dotProduct"))); // define the index model using the specified details SearchIndexModel indexModel = new SearchIndexModel( indexName, definition, SearchIndexType.vectorSearch()); // Create the index using the model try { List<String> result = collection.createSearchIndexes(Collections.singletonList(indexModel)); System.out.println("Successfully created a vector index named: " + result); } catch (Exception e) { throw new RuntimeException(e); } // Wait for Atlas to build the index and make it queryable System.out.println("Polling to confirm the index has completed building."); System.out.println("It may take up to a minute for the index to build before you can query using it."); ListSearchIndexesIterable<Document> searchIndexes = collection.listSearchIndexes(); Document doc = null; while (doc == null) { try (MongoCursor<Document> cursor = searchIndexes.iterator()) { if (!cursor.hasNext()) { break; } Document current = cursor.next(); String name = current.getString("name"); boolean queryable = current.getBoolean("queryable"); if (name.equals(indexName) && queryable) { doc = current; } else { Thread.sleep(500); } } catch (Exception e) { throw new RuntimeException(e); } } System.out.println(indexName + " index is ready to query"); } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } Substitua o valor do espaço reservado
<dimensions>
pela variável apropriada para o modelo que você usou:dimensionsHuggingFaceModel
:1024
dimensões (modelo "mixedbread-ai/mxbai-embed-large-v1")dimensionsOpenAiModel
:1536
dimensões (modelo "text-embedding-3-small")
Observação
O número de dimensões é determinado pelo modelo utilizado para gerar as incorporações. Se você adaptar este código para usar um modelo diferente, certifique-se de passar o valor correto para
numDimensions
. Consulte também a seção Escolhendo um modelo de incorporação.Salve e execute o arquivo. A saída se assemelha a:
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
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
VectorQuery.java
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
VectorQuery.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.search.FieldSearchPath; import org.bson.BsonArray; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.List; import static com.mongodb.client.model.Aggregates.project; import static com.mongodb.client.model.Aggregates.vectorSearch; import static com.mongodb.client.model.Projections.exclude; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaVectorSearchScore; import static com.mongodb.client.model.search.SearchPath.fieldPath; import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions; import static java.util.Arrays.asList; public class VectorQuery { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_db"); MongoCollection<Document> collection = database.getCollection("embeddings"); // define $vectorSearch query options String query = "ocean tragedy"; EmbeddingProvider embeddingProvider = new EmbeddingProvider(); BsonArray embeddingBsonArray = embeddingProvider.getEmbedding(query); List<Double> embedding = new ArrayList<>(); for (BsonValue value : embeddingBsonArray.stream().toList()) { embedding.add(value.asDouble().getValue()); } // define $vectorSearch pipeline String indexName = "vector_index"; FieldSearchPath fieldSearchPath = fieldPath("embedding"); int limit = 5; List<Bson> pipeline = asList( vectorSearch( fieldSearchPath, embedding, indexName, limit, exactVectorSearchOptions() ), project( fields(exclude("_id"), include("text"), metaVectorSearchScore("score")))); // run query and print results List<Document> results = collection.aggregate(pipeline).into(new ArrayList<>()); if (results.isEmpty()) { System.out.println("No results found."); } else { results.forEach(doc -> { System.out.println("Text: " + doc.getString("text")); System.out.println("Score: " + doc.getDouble("score")); }); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } Salve e execute o arquivo. O resultado se assemelha a um dos seguintes, dependendo do modelo usado:
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
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_airbnb.listingsAndReviews
que especifica o campo embeddings
como o tipo de vetor e a medida de similaridade como euclidean
.
Crie um arquivo chamado
CreateIndex.java
e cole o seguinte código:CreateIndex.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.ListSearchIndexesIterable; import com.mongodb.client.MongoCursor; import com.mongodb.client.model.SearchIndexModel; import com.mongodb.client.model.SearchIndexType; import org.bson.Document; import org.bson.conversions.Bson; import java.util.Collections; import java.util.List; public class CreateIndex { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_airbnb"); MongoCollection<Document> collection = database.getCollection("listingsAndReviews"); // define the index details String indexName = "vector_index"; int dimensionsHuggingFaceModel = 1024; int dimensionsOpenAiModel = 1536; Bson definition = new Document( "fields", Collections.singletonList( new Document("type", "vector") .append("path", "embeddings") .append("numDimensions", <dimensions>) // replace with var for the model used .append("similarity", "dotProduct") .append('quantization', "scalar"))); // define the index model using the specified details SearchIndexModel indexModel = new SearchIndexModel( indexName, definition, SearchIndexType.vectorSearch()); // create the index using the model try { List<String> result = collection.createSearchIndexes(Collections.singletonList(indexModel)); System.out.println("Successfully created a vector index named: " + result); System.out.println("It may take up to a minute for the index to build before you can query using it."); } catch (Exception e) { throw new RuntimeException(e); } // wait for Atlas to build the index and make it queryable System.out.println("Polling to confirm the index has completed building."); ListSearchIndexesIterable<Document> searchIndexes = collection.listSearchIndexes(); Document doc = null; while (doc == null) { try (MongoCursor<Document> cursor = searchIndexes.iterator()) { if (!cursor.hasNext()) { break; } Document current = cursor.next(); String name = current.getString("name"); boolean queryable = current.getBoolean("queryable"); if (name.equals(indexName) && queryable) { doc = current; } else { Thread.sleep(500); } } catch (Exception e) { throw new RuntimeException(e); } } System.out.println(indexName + " index is ready to query"); } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } Substitua o valor do espaço reservado
<dimensions>
pela variável apropriada para o modelo que você usou:dimensionsHuggingFaceModel
:1024
dimensões (código aberto)dimensionsOpenAiModel
:1536
dimensões
Observação
O número de dimensões é determinado pelo modelo utilizado para gerar as incorporações. Se você estiver usando um modelo diferente, certifique-se de passar o valor correto para
numDimensions
. Consulte também a seção Escolhendo um modelo de incorporação.Salve e execute o arquivo. A saída se assemelha a:
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
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
VectorQuery.java
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
VectorQuery.javaimport com.mongodb.MongoException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.search.FieldSearchPath; import org.bson.BsonArray; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; import java.util.ArrayList; import java.util.List; import static com.mongodb.client.model.Aggregates.project; import static com.mongodb.client.model.Aggregates.vectorSearch; import static com.mongodb.client.model.Projections.exclude; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaVectorSearchScore; import static com.mongodb.client.model.search.SearchPath.fieldPath; import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions; import static java.util.Arrays.asList; public class VectorQuery { public static void main(String[] args) { String uri = System.getenv("ATLAS_CONNECTION_STRING"); if (uri == null || uri.isEmpty()) { throw new IllegalStateException("ATLAS_CONNECTION_STRING env variable is not set or is empty."); } // establish connection and set namespace try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_airbnb"); MongoCollection<Document> collection = database.getCollection("listingsAndReviews"); // define the query and get the embedding String query = "beach house"; EmbeddingProvider embeddingProvider = new EmbeddingProvider(); BsonArray embeddingBsonArray = embeddingProvider.getEmbedding(query); List<Double> embedding = new ArrayList<>(); for (BsonValue value : embeddingBsonArray.stream().toList()) { embedding.add(value.asDouble().getValue()); } // define $vectorSearch pipeline String indexName = "vector_index"; FieldSearchPath fieldSearchPath = fieldPath("embeddings"); int limit = 5; List<Bson> pipeline = asList( vectorSearch( fieldSearchPath, embedding, indexName, limit, exactVectorSearchOptions()), project( fields(exclude("_id"), include("summary"), metaVectorSearchScore("score")))); // run query and print results List<Document> results = collection.aggregate(pipeline).into(new ArrayList<>()); if (results.isEmpty()) { System.out.println("No results found."); } else { results.forEach(doc -> { System.out.println("Summary: " + doc.getString("summary")); System.out.println("Score: " + doc.getDouble("score")); }); } } catch (MongoException me) { throw new RuntimeException("Failed to connect to MongoDB ", me); } catch (Exception e) { throw new RuntimeException("Operation failed: ", e); } } } Salve e execute o arquivo. O resultado se assemelha a um dos seguintes, dependendo do modelo usado:
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
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_db.embeddings
que especifica o campo embedding
como o tipo de vetor e a medida de similaridade como dotProduct
.
Crie um arquivo chamado
create-index.js
e cole o código a seguir.create-index.jsimport { MongoClient } from 'mongodb'; // connect to your Atlas deployment const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { const database = client.db("sample_db"); const collection = database.collection("embeddings"); // define your Atlas Vector Search index const index = { name: "vector_index", type: "vectorSearch", definition: { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": <dimensions> } ] } } // run the helper method const result = await collection.createSearchIndex(index); console.log(result); } finally { await client.close(); } } run().catch(console.dir); Substitua o valor do espaço reservado
<dimensions>
por768
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Salve o arquivo e execute o seguinte comando:
node --env-file=.env create-index.js
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
vector-query.js
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
vector-query.jsimport { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // MongoDB connection URI and options const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { // Connect to the MongoDB client await client.connect(); // Specify the database and collection const database = client.db("sample_db"); const collection = database.collection("embeddings"); // Generate embedding for the search query const queryEmbedding = await getEmbedding("ocean tragedy"); // Define the sample vector search pipeline const pipeline = [ { $vectorSearch: { index: "vector_index", queryVector: queryEmbedding, path: "embedding", exact: true, limit: 5 } }, { $project: { _id: 0, text: 1, score: { $meta: "vectorSearchScore" } } } ]; // run pipeline const result = collection.aggregate(pipeline); // print results for await (const doc of result) { console.dir(JSON.stringify(doc)); } } finally { await client.close(); } } run().catch(console.dir); Salve o arquivo e execute o seguinte comando:
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}
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Conclua as etapas a seguir para criar um índice na coleção sample_airbnb.listingsAndReviews
que especifica o campo embedding
como o tipo de vetor e a medida de similaridade como euclidean
.
Crie um arquivo chamado
create-index.js
e cole o código a seguir.create-index.jsimport { MongoClient } from 'mongodb'; // connect to your Atlas deployment const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { const database = client.db("sample_airbnb"); const collection = database.collection("listingsAndReviews"); // Define your Atlas Vector Search index const index = { name: "vector_index", type: "vectorSearch", definition: { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": <dimensions>, "quantization": "scalar" } ] } } // Call the method to create the index const result = await collection.createSearchIndex(index); console.log(result); } finally { await client.close(); } } run().catch(console.dir); Substitua o valor do espaço reservado
<dimensions>
por768
se você usou o modelo de código aberto e1536
se você usou o modelo do OpenAI.Salve o arquivo e execute o seguinte comando:
node --env-file=.env create-index.js
Observação
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Crie um arquivo chamado
vector-query.js
e cole o código a seguir.Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
vector-query.jsimport { MongoClient } from 'mongodb'; import { getEmbedding } from './get-embeddings.js'; // MongoDB connection URI and options const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { // Connect to the MongoDB client await client.connect(); // Specify the database and collection const database = client.db("sample_airbnb"); const collection = database.collection("listingsAndReviews"); // Generate embedding for the search query const queryEmbedding = await getEmbedding("beach house"); // Define the sample vector search pipeline const pipeline = [ { $vectorSearch: { index: "vector_index", queryVector: queryEmbedding, path: "embedding", exact: true, limit: 5 } }, { $project: { _id: 0, summary: 1, score: { $meta: "vectorSearchScore" } } } ]; // run pipeline const result = collection.aggregate(pipeline); // print results for await (const doc of result) { console.dir(JSON.stringify(doc)); } } finally { await client.close(); } } run().catch(console.dir); Salve o arquivo e execute o seguinte comando:
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}
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Cole o código a seguir no seu notebook.
Este código cria um índice na sua collection que especifica o seguinte:
BSON-Float32-Embedding
,BSON-Int8-Embedding
eBSON-Int1-Embedding
campos como os campos de tipo de vetor.euclidean
como a função de similaridade para incorporações doint1
edotProduct
como o tipo de similaridade para incorporações dofloat32
eint8
.768
como o número de dimensões nas incorporações.
from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "BSON-Float32-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int8-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int1-Embedding", "similarity": "euclidean", "numDimensions": 768 } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) Execute o código.
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Cole o código a seguir no seu notebook.
Este código cria um índice na sua collection e especifica o
embedding
campo como o tipo de vetor, a função de similaridade comodotProduct
e o número de dimensões1536
como. Ele também permite a quantização escalar automática para os vetores noembedding
campo para processamento eficiente de seus dados vetoriais.from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": 1536, "quantization": "scalar" } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) Execute o código.
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para uma query de pesquisa vetorial e execute a consulta.
Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Converte a incorporação de consulta
float32
paraint8
int1
subtipos de vetor BSON, e.Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
Observação
Pode levar algum tempo para que a query seja concluída.
import pymongo from bson.binary import Binary # Prepare your query query_text = "ocean tragedy" # Generate embedding for the search query query_float32_embeddings = get_embedding(query_text, precision="float32") query_int8_embeddings = get_embedding(query_text, precision="int8") query_int1_embeddings = get_embedding(query_text, precision="ubinary") # Convert each embedding to BSON format query_bson_float32_embeddings = generate_bson_vector(query_float32_embeddings, BinaryVectorDtype.FLOAT32) query_bson_int8_embeddings = generate_bson_vector(query_int8_embeddings, BinaryVectorDtype.INT8) query_bson_int1_embeddings = generate_bson_vector(query_int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Define vector search pipeline for each precision pipelines = [] for query_embedding, path in zip( [query_bson_float32_embeddings, query_bson_int8_embeddings, query_bson_int1_embeddings], ["BSON-Float32-Embedding", "BSON-Int8-Embedding", "BSON-Int1-Embedding"] ): pipeline = [ { "$vectorSearch": { "index": "vector_index", # Adjust if necessary "queryVector": query_embedding, "path": path, "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "data": 1, "score": { "$meta": "vectorSearchScore" } } } ] pipelines.append(pipeline) # Execute the search for each precision for pipeline in pipelines: print(f"Results for {pipeline[0]['$vectorSearch']['path']}:") results = collection.aggregate(pipeline) # Print results for i in results: print(i)
Results for BSON-Float32-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.7661113739013672} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.7050272822380066} {'data': 'The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.', 'score': 0.7024770379066467} {'data': 'Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.', 'score': 0.7011005282402039} {'data': 'E.T. the Extra-Terrestrial: A young boy befriends an alien stranded on Earth and helps him return home.', 'score': 0.6877288818359375} Results for BSON-Int8-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.5} {'data': 'The Lion King: Lion cub and future king Simba searches for his identity', 'score': 0.5} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.5} {'data': "Inception: A skilled thief is given a chance at redemption if he can successfully implant an idea into a person's subconscious.", 'score': 0.5} {'data': 'The Godfather: The aging patriarch of a powerful crime family transfers control of his empire to his reluctant son.', 'score': 0.5} Results for BSON-Int1-Embedding: {'data': 'Titanic: The story of the 1912 sinking of the largest luxury liner ever built', 'score': 0.671875} {'data': 'The Shawshank Redemption: A banker is sentenced to life in Shawshank State Penitentiary for the murders of his wife and her lover.', 'score': 0.6484375} {'data': 'Avatar: A marine is dispatched to the moon Pandora on a unique mission', 'score': 0.640625} {'data': 'Back to the Future: A teenager accidentally travels back in time and must ensure his parents fall in love.', 'score': 0.6145833134651184} {'data': 'Jurassic Park: Scientists clone dinosaurs to populate an island theme park, which soon goes awry.', 'score': 0.61328125}
# Generate embedding for the search query query_embedding = get_embedding("ocean tragedy") # Sample vector search pipeline pipeline = [ { "$vectorSearch": { "index": "vector_index", "queryVector": query_embedding, "path": "embedding", "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "text": 1, "score": { "$meta": "vectorSearchScore" } } } ] # Execute the search results = collection.aggregate(pipeline) # Print results for i in results: print(i)
{"text":"Titanic: The story of the 1912 sinking of the largest luxury liner ever built","score":0.4551968574523926} {"text":"Avatar: A marine is dispatched to the moon Pandora on a unique mission","score":0.4050074517726898} {"text":"The Lion King: Lion cub and future king Simba searches for his identity","score":0.3594386577606201}
Criar o índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Cole o código a seguir no seu notebook.
Este código cria um índice na sua collection que especifica o seguinte:
BSON-Float32-Embedding
,BSON-Int8-Embedding
eBSON-Int1-Embedding
campos como os campos de tipo de vetor.euclidean
como a função de similaridade para incorporações doint1
edotProduct
como o tipo de similaridade para incorporações dofloat32
eint8
.768
como o número de dimensões nas incorporações.
from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "BSON-Float32-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int8-Embedding", "similarity": "dotProduct", "numDimensions": 768 }, { "type": "vector", "path": "BSON-Int1-Embedding", "similarity": "euclidean", "numDimensions": 768 } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) Execute o código.
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Para habilitar queries de pesquisa vetorial em seus dados, você deve criar um índice do Atlas Vector Search em sua coleção.
Cole o código a seguir no seu notebook.
Este código cria um índice na sua collection e especifica o
embedding
campo como o tipo de vetor, a função de similaridade comodotProduct
e o número de dimensões1536
como. Ele também permite a quantização escalar automática para os vetores noembedding
campo para processamento eficiente de seus dados vetoriais.from pymongo.operations import SearchIndexModel # Create your index model, then create the search index search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "path": "embedding", "similarity": "dotProduct", "numDimensions": 1536, "quantization": "scalar" } ] }, name="vector_index", type="vectorSearch", ) collection.create_search_index(model=search_index_model) Execute o código.
O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.
Para saber mais, consulte Criar um índice do Atlas Vector Search.
Crie incorporações para queries de pesquisa vetorial e execute uma query.
Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Converte a incorporação de consulta
float32
paraint8
int1
subtipos de vetor BSON, e.Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
import pymongo from bson.binary import Binary # Prepare your query query_text = "beach house" # Generate embedding for the search query query_float32_embeddings = get_embedding(query_text, precision="float32") query_int8_embeddings = get_embedding(query_text, precision="int8") query_int1_embeddings = get_embedding(query_text, precision="ubinary") # Convert each embedding to BSON format query_bson_float32_embeddings = generate_bson_vector(query_float32_embeddings, BinaryVectorDtype.FLOAT32) query_bson_int8_embeddings = generate_bson_vector(query_int8_embeddings, BinaryVectorDtype.INT8) query_bson_int1_embeddings = generate_bson_vector(query_int1_embeddings, BinaryVectorDtype.PACKED_BIT) # Define vector search pipeline for each precision pipelines = [] for query_embedding, path in zip( [query_bson_float32_embeddings, query_bson_int8_embeddings, query_bson_int1_embeddings], ["BSON-Float32-Embedding", "BSON-Int8-Embedding", "BSON-Int1-Embedding"] ): pipeline = [ { "$vectorSearch": { "index": "vector_index", # Adjust if necessary "queryVector": query_embedding, "path": path, "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "summary": 1, "score": { "$meta": "vectorSearchScore" } } } ] pipelines.append(pipeline) # Execute the search for each precision for pipeline in pipelines: print(f"Results for {pipeline[0]['$vectorSearch']['path']}:") results = collection.aggregate(pipeline) # Print results for i in results: print(i)
Results for BSON-Float32-Embedding: {'summary': 'Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.', 'score': 0.7847104072570801} {'summary': 'The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.', 'score': 0.7780507802963257} {'summary': "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", 'score': 0.7723637223243713} {'summary': 'Room 2 Private room in charming recently renovated federation guest house at Coogee Beach. Prices are per room for 2 People only. A queen and a single bed. Not suitable for group booking All rooms have TV, desk, wardrobe, beds, unlimited wifi 2 mins from the beach, cafes and transport. This is not a party house but a safe and clean place to stay. Share bathrooms and kitchen... All common areas are cleaned daily.', 'score': 0.7665778398513794} {'summary': 'A friendly apartment block where everyone knows each other and there is a strong communal vibe. Property has a huge backyard with vege garden and skate ramp. 7min walk to the beach and 2min to buses.', 'score': 0.7593404650688171} Results for BSON-Int8-Embedding: {'summary': 'Fantastic duplex apartment with three bedrooms, located in the historic area of Porto, Ribeira (Cube) - UNESCO World Heritage Site. Centenary building fully rehabilitated, without losing their original character.', 'score': 0.5} {'summary': 'One bedroom + sofa-bed in quiet and bucolic neighbourhood right next to the Botanical Garden. Small garden, outside shower, well equipped kitchen and bathroom with shower and tub. Easy for transport with many restaurants and basic facilities in the area.', 'score': 0.5} {'summary': "A short distance from Honolulu's billion dollar mall, and the same distance to Waikiki. Parking included. A great location that work perfectly for business, education, or simple visit. Experience Yacht Harbor views and 5 Star Hilton Hawaiian Village.", 'score': 0.5} {'summary': 'Here exists a very cozy room for rent in a shared 4-bedroom apartment. It is located one block off of the JMZ at Myrtle Broadway. The neighborhood is diverse and appeals to a variety of people.', 'score': 0.5} {'summary': 'Quarto com vista para a Lagoa Rodrigo de Freitas, cartão postal do Rio de Janeiro. Linda Vista. 1 Quarto e 1 banheiro Amplo, arejado, vaga na garagem. Prédio com piscina, sauna e playground. Fácil acesso, próximo da praia e shoppings.', 'score': 0.5} Results for BSON-Int1-Embedding: {'summary': 'Having a large airy living room. The apartment is well divided. Fully furnished and cozy. The building has a 24h doorman and camera services in the corridors. It is very well located, close to the beach, restaurants, pubs and several shops and supermarkets. And it offers a good mobility being close to the subway.', 'score': 0.6901041865348816} {'summary': 'Cozy and comfortable apartment. Ideal for families and vacations. 3 bedrooms, 2 of them suites. Located 20-min walk to the beach and close to the Rio 2016 Olympics Venues. Situated in a modern and secure condominium, with many entertainment available options around.', 'score': 0.6731770634651184} {'summary': "A beautiful and comfortable 1 Bedroom Air Conditioned Condo in Makaha Valley - stunning Ocean & Mountain views All the amenities of home, suited for longer stays. Full kitchen & large bathroom. Several gas BBQ's for all guests to use & a large heated pool surrounded by reclining chairs to sunbathe. The Ocean you see in the pictures is not even a mile away, known as the famous Makaha Surfing Beach. Golfing, hiking,snorkeling paddle boarding, surfing are all just minutes from the front door.", 'score': 0.6731770634651184} {'summary': 'The Apartment has a living room, toilet, bedroom (suite) and American kitchen. Well located, on the Copacabana beach block a 05 Min. walk from Ipanema beach (Arpoador). Internet wifi, cable tv, air conditioning in the bedroom, ceiling fans in the bedroom and living room, kitchen with microwave, cooker, Blender, dishes, cutlery and service area with fridge, washing machine, clothesline for drying clothes and closet with several utensils for use. The property boasts 45 m2.', 'score': 0.671875} {'summary': 'THIS IS A VERY SPACIOUS 1 BEDROOM FULL CONDO (SLEEPS 4) AT THE BEAUTIFUL VALLEY ISLE RESORT ON THE BEACH IN LAHAINA, MAUI!! YOU WILL LOVE THE PERFECT LOCATION OF THIS VERY NICE HIGH RISE! ALSO THIS SPACIOUS FULL CONDO, FULL KITCHEN, BIG BALCONY!!', 'score': 0.6705729365348816}
Para executar uma query de pesquisa vetorial, gere um vetor de query para passar para seu pipeline de agregação.
Por exemplo, este código faz o seguinte:
Cria uma inserção de query de amostra chamando a função de inserção que você definiu.
Passa a incorporação no campo
queryVector
e especifica o caminho para pesquisar no agregação pipeline.Especifica o estágio no
$vectorSearch
pipeline para realizar uma pesquisa ENN sobre suas incorporações.Executa uma query de pesquisa vetorial de amostra nas incorporações armazenadas na collection.
Retorna documentos semanticamente semelhantes em ordem de relevância e sua pontuação de pesquisa vetorial.
# 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}
Considerações
Considere os seguintes fatores ao criar incorporações vetoriais:
Escolha de um método para criar incorporações
Para criar incorporações vetoriais, você deve usar um modelo de incorporação. Modelos de incorporação são algoritmos usados para converter dados em incorporações. Você pode escolher um dos seguintes métodos para se conectar a um modelo de incorporação e criar incorporações vetoriais:
Método | Descrição |
---|---|
Carregue um modelo de código aberto | Se você não tiver uma chave de API para um modelo de incorporação proprietário, carregue um modelo de incorporação de código aberto localmente a partir do seu aplicativo. |
Use um modelo proprietário | A maioria dos provedores de AI oferece APIs para seus modelos de incorporação proprietários que você pode usar para criar incorporações vetoriais. |
Aproveite uma integração | Você pode integrar o Atlas Vector Search com estruturas de código aberto e serviços de IA para se conectar rapidamente a modelos de incorporação proprietários e de código aberto e gerar incorporações vetoriais para o Atlas Vector Search. Para saber mais, consulte Integrar o Vector Search com tecnologias de IA. |
Escolha de um modelo de incorporação
O modelo de incorporação escolhido afeta os resultados da consulta e determina o número de dimensões que você especifica no índice do Atlas Vector Search. Cada modelo oferece vantagens diferentes, dependendo de seus dados e do caso de uso.
Para uma lista de modelos de incorporação populares, consulte Massive Text Embedding benchmark (MTEB). Essa lista fornece insights sobre vários modelos de incorporação de texto de código aberto e proprietários e permite filtrar modelos por caso de uso, tipo de modelo e métricas específicas do modelo.
Ao escolher um modelo de incorporação para o Atlas Vector Search, considere as seguintes métricas:
Dimensões de incorporação: o comprimento da incorporação do vetor.
Embeddings menores são mais eficientes em termos de armazenamento, enquanto embeddings maiores podem capturar relacionamentos mais sutis em seus dados. O modelo que você escolher deve encontrar um equilíbrio entre eficiência e complexidade.
Máximo de tokens : o número de tokens que podem ser compactados em uma única incorporação.
Tamanho do modelo: o tamanho do modelo em gigabytes.
Embora os modelos maiores tenham desempenho melhor, eles exigem mais recursos computacionais à medida que você dimensiona o Atlas Vector Search para produção.
Média de recuperação: uma pontuação que mede o desempenho dos sistemas de recuperação.
Uma pontuação mais alta indica que o modelo é melhor na classificação de documentos relevantes no topo da lista de resultados recuperados. Essa pontuação é importante ao escolher um modelo para aplicativos RAG .
Validação das suas incorporações
Considere as seguintes estratégias para garantir que suas incorporações estejam corretas e ideais:
Teste suas funções e scripts.
Gerar incorporações leva tempo e recursos computacionais. Antes de criar incorporações a partir de grandes conjuntos ou coleções de dados, teste se suas funções ou scripts de incorporação funcionam conforme o esperado em um pequeno subconjunto de seus dados.
Criar incorporações em lotes.
Se você quiser gerar embeddings a partir de um grande conjunto de dados ou de uma collection com muitos documentos, crie-os em lotes para evitar problemas de memória e otimizar o desempenho.
Avalie o desempenho.
Execute queries de teste para verificar se os resultados da pesquisa são relevantes e classificados com precisão.
Para saber mais sobre como avaliar seus resultados e ajustar o desempenho de seus índices e consultas, consulte Como medir a precisão dos resultados da consulta e melhorar o desempenho da Vector Search .
Solução de problemas
Considere as seguintes estratégias se você encontrar problemas em suas incorporações:
Verifique seu ambiente.
Verifique se as dependências necessárias estão instaladas e atualizadas. Versões de bibliotecas conflitantes podem causar comportamento inesperado. Certifique-se de que não existam conflitos criando um novo ambiente e instalando apenas os pacotes necessários.
Observação
Se estiver usando o Colab, certifique-se de que o endereço IP da sessão do notebook esteja incluído na lista de acesso do projeto Atlas.
Monitore o uso da memória.
Se você tiver problemas de desempenho, verifique a utilização da RAM, da CPU e do disco para identificar possíveis gargalos. Para ambientes hospedados, como notebooks Colab ou Jupyter, garanta que sua instância seja provisionada com recursos suficientes e faça upgrade da instância se necessário.
Garanta dimensões consistentes.
Verifique se a definição do índice do Atlas Vector Search corresponde às dimensões dos embeddings armazenados no Atlas e se os incorporações de query correspondem às dimensões dos embeddings indexados. Caso contrário, você poderá encontrar erros ao executar consultas de pesquisa vetorial.
Para solucionar problemas específicos, consulte Solução de problemas.
Próximos passos
Depois de aprender a criar embeddings e consultá-los com o Atlas Vector Search, comece a criar aplicativos de IA generativos implementando a geração aumentada de recuperação (RAG):
Geração aumentada de recuperação (RAG) com Atlas Vector Search
Crie uma implementação de RAG local com o Atlas Vector Search
Você também pode converter suas incorporações em vetores BSON para armazenamento e ingestão eficientes de vetores no Atlas. Para saber mais, consulte Como consumir vetores pré-quantizados.