<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Laurent Saint-Félix - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Laurent Saint-Félix - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/pt/search-labs/author/laurent-saint-felix</link>
    </image>
    <link>https://www.elastic.co/pt/search-labs/author/laurent-saint-felix</link>
    <atom:link href="https://www.elastic.co/pt/search-labs/rss/author/laurent-saint-felix.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[pt]]></language>
    <lastBuildDate>Mon, 05 Oct 2026 14:54:48 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Introdução do suporte ao Elasticsearch no Google MCP Toolbox for Databases]]></title>
    <description><![CDATA[Veja como o suporte ao Elasticsearch agora está disponível no Google MCP Toolbox for Databases e adote as ferramentas ES|QL para integrar seu índice com segurança a qualquer cliente MCP.]]></description>
    <content:encoded><![CDATA[<p>Neste artigo, vamos explicar como usar o Google MCP Toolbox com o <a href="https://github.com/elastic/elasticsearch">Elasticsearch</a> para construir uma ferramenta simples de extração de informações de um índice do Elasticsearch.</p><p>Recentemente, contribuímos para o projeto open source <a href="https://github.com/googleapis/genai-toolbox">Google MCP Toolbox for Databases</a>, adicionando suporte ao Elasticsearch como banco de dados.</p><p>Com esse novo recurso, agora você pode usar o Google MCP Toolbox para se conectar ao Elasticsearch e "conversar" diretamente com seus dados.</p><h2>Elasticsearch</h2><p>Precisamos ter uma instância do Elasticsearch em execução. Você pode ativar uma avaliação gratuita no <a href="https://www.elastic.co/cloud">Elastic Cloud</a> ou instalá-lo localmente usando o <a href="https://github.com/elastic/start-local">script start-local</a>:</p>curl -fsSL https://elastic.co/start-local | sh<p>Isso instalará o Elasticsearch e o Kibana no seu computador e gerará uma chave API para ser usada na configuração do Google MCP Toolbox.</p><p>A chave API será mostrada como saída do comando anterior e armazenada em um arquivo .env na pasta elastic-start-local.</p><h2>Instale o conjunto de dados de exemplo</h2><p>Após a instalação, você pode fazer login no Kibana usando o nome do usuário <em>elastic</em> e a senha gerada pelo script start-local (armazenada em um arquivo .env).</p><p>Você pode instalar o conjunto de dados de <strong>pedidos de comércio eletrônico </strong>disponível no Kibana. Inclui um único índice chamado <strong>kibana_sample_data_ecommerce</strong> contendo informações sobre 4.675 pedidos de um website de comércio eletrônico. Para cada pedido, temos as seguintes informações:</p><ul><li><p>Informações do cliente (nome, ID, data de nascimento, e-mail, etc.)</p></li><li><p>Data do pedido</p></li><li><p>ID do pedido</p></li><li><p>Produtos (lista de todos os produtos com preço, quantidade, ID, categoria, desconto, etc.)</p></li><li><p>SKU</p></li><li><p>Preço total (sem impostos, com impostos)</p></li><li><p>Quantidade total</p></li><li><p>Informações geográficas (cidade, país, continente, localização, região)</p></li></ul><p>Para instalar os dados de exemplo, abra a página <strong>Integrações</strong> no Kibana (busque por “Integração” na barra de busca superior) e instale os “Dados de Exemplo”. Confira os detalhes na documentação aqui: <a href="https://www.elastic.co/docs/explore-analyze/#gs-get-data-into-kibana">https://www.elastic.co/docs/explore-analyze/#gs-get-data-into-kibana</a>.</p><p>O objetivo deste artigo é mostrar como é fácil configurar o Google MCP Toolbox para se conectar ao Elasticsearch e interagir com o <strong>índice kibana_sample_data_ecommerce</strong> usando linguagem natural.</p><h2>Google MCP Toolbox</h2><p>O Google MCP Toolbox é um servidor MCP open source projetado para facilitar a interação de aplicações e agentes de IA com bancos de dados de forma segura e eficiente. Antes chamado de "GenAI Toolbox for Databases", o projeto foi renomeado após adotar total compatibilidade com o <a href="https://www.anthropic.com/news/model-context-protocol">Protocolo de Contexto de Modelo</a> (MCP). Seu objetivo é eliminar o trabalho pesado tradicionalmente exigido ao conectar agentes a bancos de dados, lidando com agrupamento de conexões, autenticação, observabilidade e outras preocupações operacionais nos bastidores.</p><p>Essencialmente, o Toolbox permite que desenvolvedores definam ferramentas reutilizáveis e de alto nível que encapsulam interações com bancos de dados. Essas ferramentas podem então ser invocadas por qualquer cliente que cumpra o MCP — como um agente de IA — sem exigir que o cliente implemente consultas SQL de baixo nível ou gerencie conexões de banco de dados. Essa abordagem reduz drasticamente a quantidade de código padrão necessário para construir agentes conscientes de banco de dados, tornando possível integrar operações avançadas de dados em apenas algumas linhas de lógica de aplicação. Uma vez definida uma ferramenta, ela pode ser compartilhada entre vários agentes, frameworks ou linguagens (Figura 1).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte90070297ee83546/6a16fa29964cea694b08b972/137cea290bb70ad5da21853f9a6358cef4cf7451-1248x1056.png" alt="" /><p>Uma grande vantagem de usar o Toolbox é o modelo de segurança integrado. Fluxos de autenticação, como OAuth2 e OIDC, são aceitos de forma nativa, permitindo que os desenvolvedores evitem manipular ou armazenar credenciais confidenciais de bancos de dados em agentes. A plataforma também fornece recursos de observabilidade, incluindo métricas e rastreamento, no OpenTelemetry, que é essencial para depuração, monitoramento e implantações de produção. No geral, o MCP Toolbox serve como uma interface unificada, segura e extensível para interagir com seus dados de qualquer sistema habilitado pelo MCP.</p><h2>Como instalar o MCP Toolbox</h2><p>Você pode instalar o servidor MCP Toolbox no Linux usando o seguinte comando:</p>export VERSION=0.21.0
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
chmod +x toolbox<p>Para instalá-lo no macOS ou Windows, siga as instruções detalhadas <a href="https://googleapis.github.io/genai-toolbox/getting-started/introduction/#installing-the-server">aqui</a>.</p><h2>Configure o Toolbox para Elasticsearch</h2><p>Para configurar o MCP Toolbox para Elasticsearch, precisamos criar um arquivo <strong>tools.yaml</strong> , conforme segue:</p>sources:
  my-cluster:
    kind: elasticsearch
    addresses:
      - http://localhost:9200
    apikey: &lt;insert-here-api-key&gt;

tools:
  customer-orders:
    kind: elasticsearch-esql
    source: my-cluster
    description: Get the orders made by a customer identified by name.
    query: |
    	FROM kibana_sample_data_ecommerce | WHERE MATCH(customer_full_name, ?name, {"operator": "AND"})
    parameters:
      - name: name
        type: string
        description: The customer name.

toolsets:
  elasticsearch-tools:
    - customer-orders<p>Você precisa trocar o valor <strong>&lt;insert-here-api-key&gt;</strong> por uma chave API válida do Elasticsearch. Se você estiver rodando o Elasticsearch localmente usando o start-local, pode encontrar a chave API no arquivo .env gerado pelo start-local, sob a variável <strong>ES_LOCAL_API_KEY</strong> . Se você estiver usando o Elastic Cloud, poderá gerar uma chave de API seguindo o procedimento descrito <a href="https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys">aqui</a>.</p><p>As ferramentas anteriores contêm a seguinte consulta ES|QL para Elasticsearch:</p><p>Se você não conhece o ES|QL, é uma linguagem de consulta desenvolvida pela Elastic, semelhante ao SQL, que pode ser usada para buscar em um ou mais índices. Saiba mais sobre ES|QL na documentação oficial <a href="https://www.elastic.co/docs/reference/query-languages/esql">aqui</a>.</p><p>A consulta acima busca todos os pedidos armazenados no <strong>índice kibana_sample_data_ecommerce</strong> que contêm o nome do cliente especificado, usando o parâmetro <strong>?name</strong> (o ponto de interrogação indica um parâmetro).</p><p>O nome do cliente é definido na configuração YAML anterior usando a string de tipo e a descrição "O nome do cliente".</p><p>Essa ferramenta pode ser usada para responder a perguntas sobre os pedidos de um cliente - por exemplo: <em>Quantos pedidos o cliente Foo fez em outubro de 2025?</em></p><p>As descrições das ferramentas e seus parâmetros são essenciais para extrair as informações relevantes da solicitação em linguagem natural do usuário. Essa extração é realizada usando o recurso de <strong>chamada de função</strong> de um modelo de linguagem grande (LLM). Na prática, um LLM pode determinar qual função (ferramenta) precisa ser executada para obter as informações necessárias, juntamente com os parâmetros apropriados para essa função.</p><p>Para saber mais sobre chamadas de função, sugerimos o artigo <a href="https://www.elastic.co/search-labs/blog/function-calling-with-elastic">Chamadas de função do OpenAI com Elasticsearch</a>, de Ashish Tiwari.</p><h2>Execute o servidor Toolbox</h2><p>Você pode executar o MCP Toolbox usando o arquivo tools.yaml anterior com o seguinte comando:</p>./toolbox --tools-file tools.yaml --ui<p>O parâmetro<strong> –ui</strong> executa uma aplicação web em <a href="http://127.0.0.1:5000/ui">http://127.0.0.1:5000/ui</a> (Figura 2).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0fb3953fae603572/6a16fa2aa6c2b92763e794fb/3caf2339b632bafd5847af1ed8b33b518a25b8a2-1600x314.png" alt="" /><p>Você pode selecionar <strong>Ferramentas</strong> &gt; <strong>customer-orders</strong> e inserir o nome do cliente no campo <strong>Nome</strong> do parâmetro (por exemplo, Gwen Sanders) e clicar no botão <strong>Executar</strong>. Você deve ver uma resposta JSON conforme a Figura 3.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca02df8c78cb39ff/6a16fa2c961e6909b5c4cd22/b167e0142afb8919d9cedf6d0fa431d33d0e55f8-1600x933.png" alt="" /><p>A configuração está concluída, e o MCP Toolbox pode executar a ferramenta <strong>customer-orders</strong> para se comunicar com o Elasticsearch, rodando o ES|QL.</p><h2>Usando o MCP Toolbox com Gemini CLI</h2><p>Podemos usar qualquer cliente MCP para nos comunicar com o MCP Toolbox for Databases. Por exemplo, podemos usar o <a href="https://github.com/google-gemini/gemini-cli">Gemini CLI</a>, uma ferramenta de linha de comando, para usar o Gemini. Você pode instalar o Gemini CLI seguindo as instruções descritas <a href="https://geminicli.com/docs/get-started/installation/">aqui</a>.</p><p>Gemini CLI oferece uma extensão pré-configurada para MCP Toolbox, disponível em <a href="https://github.com/gemini-cli-extensions/mcp-toolbox">gemini-cli-extensions/mcp-toolbox</a>. Você pode instalar esta extensão executando o seguinte comando:</p>gemini extensions install https://github.com/gemini-cli-extensions/mcp-toolbox<p>Após a instalação, você precisa ir para o diretório em que armazenou o arquivo de configuração tools.yaml do MCP Toolbox e executar a CLI do Gemini da seguinte forma (essa etapa é necessária para que a CLI do Gemini seja configurada automaticamente com o MCP Toolbox):</p>gemini<p>Você deve ver uma saída conforme a Figura 4.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7245c10b9e32cd6/6a16fa2d964cea073208b976/0f22df6d3da13c1dc50dcb560414fa7c630eb9a7-1434x341.png" alt="" /><p>Você pode verificar se a MCP Toolbox está conectada usando o seguinte comando:</p>/mcp list<p>Você deve ver a <strong>mcp_toolbox</strong> com as ferramentas<strong> de pedidos de clientes</strong> listadas (Figura 5).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte857b42dbe604203/6a16fa2f8b73cb531b189e33/97edbc40de9e44f469f6f3a09427532be167de0e-493x155.png" alt="" /><p>Se o MCP Toolbox estiver conectado à interface de comando Gemini, agora podemos tentar fazer algumas perguntas, como: "<em>Me dê os pedidos da cliente Gwen Sanders</em>." A CLI Gemini então solicitará permissão para executar a ferramenta de pedidos do cliente ao servidor mcp_toolbox (veja a Figura 6).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfb7ea752c1a39da7/6a16fa30cdacbfdf937d27ff/c052f3b5e49436903b804280c0065f67ee02444b-1432x284.png" alt="" /><p>Após a confirmação, a CLI Gemini executará a solicitação para a MCP Toolbox, recebendo uma resposta JSON como resultado e usando para formatar a resposta (Figura 7).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb9f6e04987137a9f/6a16fa320811ae2297e9fef7/7ea5128f1705951c2757af6da4b456d394d4a080-1432x734.png" alt="" /><p>A resposta da Gemini CLI emitirá um relatório indicando que Gewn Sanders fez apenas um pedido de 2 produtos, totalizando 132 euros.</p><h2>SDKs do MCP Toolbox</h2><p>O Google MCP Toolbox também oferece um SDK para acessar todas as funcionalidades de um programa escrito em Go, Python e Javascript.</p><p>Por exemplo, o Python SDK está disponível no Github na seguinte página: <a href="https://github.com/googleapis/mcp-toolbox-sdk-python">https://github.com/googleapis/mcp-toolbox-sdk-python.</a></p><p>Precisamos criar um agente simples para conectar à MCP Toolbox. Precisamos instalar os seguintes pacotes:</p>pip install toolbox-core
pip install google-adk<p>E crie um novo projeto de agente usando o comando a seguir:</p>adk create my_agent<p>Isso criará um novo diretório chamado <strong>my_agent</strong> com um <strong>arquivo agent.py</strong>.</p><p>Atualize <strong>my_agent/agent.py</strong> com o seguinte conteúdo para conectar ao Toolbox:</p>from google.adk import Agent
from google.adk.apps import App
from toolbox_core import ToolboxSyncClient

client = ToolboxSyncClient("http://127.0.0.1:5000")

root_agent = Agent(
    name='root_agent',
    model='gemini-2.5-flash',
    instruction="You are a helpful AI assistant designed to search information about a dataset of ecommerce orders.",
    tools=client.load_toolset(),
)

app = App(root_agent=root_agent, name="my_agent")<p>Crie um arquivo <strong>.env</strong> com sua chave API do Google:</p>echo 'GOOGLE_API_KEY="YOUR_API_KEY"' &gt; my_agent/.env<p>Por fim, podemos executar o agente e observar os resultados. Para executar o agente, você pode executar o seguinte comando:</p>adk run my_agent<p>Ou pode servi-lo por meio de uma interface web:</p>adk web --port 8000<p>Em ambos os casos, você pode interagir com a MCP Toolbox usando uma interface de perguntas e respostas. Por exemplo, você pode fazer a pergunta anterior: <em>Me dê os pedidos da cliente Gwen Sanders</em>.</p><p>Para saber mais sobre os diferentes SDKs, consulte <a href="https://googleapis.github.io/genai-toolbox/sdks/">esta página de documentação</a>.</p><h2>Conclusão</h2><p>Neste artigo, demonstramos a integração com o Elasticsearch para o Google MCP Toolbox for Databases. Usando um arquivo de configuração YAML simples, podemos definir um conjunto de ferramentas que traduzem perguntas de linguagem natural em consultas do Elasticsearch usando a linguagem ES|QL.</p><p>Mostramos como interagir com os conjuntos de dados kibana_sample_data_ecommerce, que contém pedidos de um website de e-commerce. Com esse arquivo de configuração, basta executar o servidor MCP Toolbox e conectar a ele a partir de qualquer cliente MCP.</p><p>Por fim, demonstramos como usar o Gemini CLI como cliente para conectar-se ao MCP Toolbox for Databases e consultar os dados de comércio eletrônico armazenados no Elasticsearch. Executamos uma consulta em linguagem natural para obter informações sobre pedidos de um cliente específico identificado pelo nome.</p><p>À medida que o ecossistema MCP continua crescendo, esse padrão — definições leves de ferramentas apoiadas por uma infraestrutura segura e pronta para produção — gera novas oportunidades para criar agentes cada vez mais capazes e com reconhecimento de dados com o mínimo esforço. Seja experimentando localmente com os conjuntos de dados de amostra da Elastic ou integrando capacidades de buscar em uma aplicação maior, o MCP Toolbox tem uma base confiável e extensível para interagir com os dados do Elasticsearch usando linguagem natural.</p><p>Para saber mais sobre o desenvolvimento de aplicações de IA agêntica, leia o artigo <a href="https://search-labs-redesign.vercel.app/search-labs/blog/ai-agentic-workflows-elastic-ai-agent-builder">Criando fluxos de trabalho de IA agêntica com Elasticsearch</a>, de Anish Mathur e Dana Juratoni.</p><p>Para saber mais informações sobre o Google MCP Toolbox, visite <a href="https://googleapis.github.io/genai-toolbox/getting-started/introduction/">https://googleapis.github.io/genai-toolbox/getting-started/introduction/</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/google-mcp-toolbox-elasticsearch-support</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/google-mcp-toolbox-elasticsearch-support</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[IA agêntica]]></category>
    <dc:creator><![CDATA[Enrico Zimuel,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72d49893c51407cf/6a16fa33cf4f2502bab2cf7e/425a48691f436ed47c9bdfaf5d561ac122b2c472-1062x668.png" length="0" type="image/png"/>
    <pubDate>Fri, 12 Dec 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Usando busca híbrida para caça de gopher com Elasticsearch e Go]]></title>
    <description><![CDATA[Aprenda como realizar buscas híbridas combinando buscas por palavra-chave e buscas vetoriais usando o Elasticsearch e o cliente Elasticsearch Go.]]></description>
    <content:encoded><![CDATA[<p>Nas partes anteriores desta série, foi demonstrado como usar o cliente Elasticsearch Go para <a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">pesquisa tradicional por palavras-chave</a> e <a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">pesquisa vetorial</a>. Esta terceira parte aborda a busca híbrida. Vamos compartilhar <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">exemplos</a> de como você pode combinar a pesquisa vetorial e a pesquisa por palavra-chave usando o <a href="https://www.elastic.co/elasticsearch/">Elasticsearch</a> e o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>.</p><h2>Pré-requisitos</h2><p>Assim como na primeira parte desta série, os seguintes pré-requisitos são necessários para este exemplo:</p><ol><li><p>Instalação do Go versão 1.21 ou posterior</p></li><li><p>Crie seu próprio repositório Go usando a estrutura recomendada e o gerenciamento de pacotes abordados na <a href="https://go.dev/doc/code">documentação do Go.</a></p></li><li><p>Criando seu próprio cluster Elasticsearch, preenchido com um conjunto de <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch#sources">páginas baseadas em roedores</a>, incluindo para o nosso amigável <a href="https://en.wikipedia.org/wiki/Gopher">Gopher</a>, da Wikipédia:</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Página do Gopher na Wikipédia" /><h2>Conectando-se ao Elasticsearch</h2><p>Lembrando que, em nossos exemplos, utilizaremos a <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">API tipada</a> oferecida pelo cliente Go. Para estabelecer uma conexão segura para qualquer consulta, é necessário configurar o cliente usando um dos seguintes métodos:</p><ol><li><p>ID da nuvem e chave de API, caso esteja utilizando o Elastic Cloud.</p></li><li><p>URL do cluster, nome de usuário, senha e certificado</p></li></ol><p>A conexão com nosso cluster localizado no Elastic Cloud seria feita da seguinte forma:</p>func GetElasticsearchClient() (*elasticsearch.TypedClient, error) {
	var cloudID = os.Getenv("ELASTIC_CLOUD_ID")
	var apiKey = os.Getenv("ELASTIC_API_KEY")

	var es, err = elasticsearch.NewTypedClient(elasticsearch.Config{
		CloudID: cloudID,
		APIKey:  apiKey,
		Logger:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

	if err != nil {
		return nil, fmt.Errorf("unable to connect: %w", err)
	}

	return es, nil
}
<p>A conexão <code>client</code> pode então ser usada para pesquisa, como demonstrado nas seções subsequentes.</p><h2>Impulsionamento manual para pesquisa híbrida</h2><p>Ao combinar qualquer conjunto de algoritmos de busca, a abordagem tradicional tem sido configurar manualmente constantes para otimizar cada tipo de consulta. Especificamente, um fator é definido para cada consulta, e o conjunto de resultados combinados é comparado ao conjunto esperado para determinar a recuperação da consulta. Em seguida, repetimos o processo para vários conjuntos de fatores e escolhemos aquele que mais se aproxima do estado desejado.</p><p>Por exemplo, combinar uma consulta de pesquisa de texto simples, ampliada por um fator de <code>0.8</code> , com uma consulta KNN com um fator menor de <code>0.2</code> pode ser feito especificando o campo <code>Boost</code> em ambos os tipos de consulta, como mostrado no exemplo abaixo:</p>func HybridSearchWithBoost(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	var k = 10
	var numCandidates = 10
	var knnBoost float32 = 0.2
	var queryBoost float32 = 0.8

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
			Field:         "text_embedding.predicted_value",
			Boost:         &amp;knnBoost,
			K:             &amp;k,
			NumCandidates: &amp;numCandidates,
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).
		Query(&amp;types.Query{
			Match: map[string]types.MatchQuery{
				"title": {
					Query: term,
					Boost: &amp;queryBoost,
				},
			},
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<p>O fator especificado na opção <code>Boost</code> para cada consulta é adicionado à pontuação do documento. Ao aumentar a pontuação da nossa consulta de correspondência por um fator maior do que a consulta knn, os resultados da consulta por palavra-chave recebem um peso maior.</p><p>O desafio da otimização manual, especialmente se você não for um especialista em buscas, é que ela exige ajustes para descobrir os fatores que levarão ao conjunto de resultados desejado. Trata-se simplesmente de experimentar valores aleatórios para ver o que o aproxima do resultado desejado.</p><h2>Fusão de classificação recíproca em pesquisa híbrida e cliente Go</h2><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">O Reciprocal Rank Fusion</a>, ou RRF, foi lançado em versão de pré-visualização técnica para busca híbrida no Elasticsearch 8.9. Tem como objetivo reduzir a curva de aprendizado associada ao ajuste fino e diminuir o tempo gasto experimentando diferentes fatores para otimizar o conjunto de resultados.</p><p>Com o RRF, a pontuação do documento é recalculada combinando as pontuações pelo algoritmo abaixo:</p>score := 0.0
// q is a query in the set of queries (vector and keyword search)
for _, q := range queries {
    // result(q) is the results 
    if document in result(q) {
        // k is a ranking constant (default 60)
        // rank(result(q), d) is the document's rank within result(q) 
        // range from 1 to the window_size (default 100)
        score +=  1.0 / (k + rank(result(q), d))
    }
}

return score
<p>A vantagem de usar o RRF é que podemos aproveitar os valores padrão adequados do Elasticsearch. A constante de classificação <code>k</code> assume o valor padrão <code>60</code>. Para proporcionar um equilíbrio entre a relevância dos documentos retornados e o desempenho da consulta ao pesquisar em grandes conjuntos de dados, o tamanho do conjunto de resultados para cada consulta considerada é limitado ao valor de <code>window_size</code>, que por padrão é <code>100</code> conforme descrito na <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html#rrf-api">documentação</a>.</p><p><code>k</code> e <code>windows_size</code> também pode ser configurado dentro da configuração <code>Rrf</code> dentro do método <code>Rank</code> no cliente Go, conforme o exemplo abaixo:</p>func HybridSearchWithRRF(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	var k = 10
	var numCandidates = 10

	// Minimum required window size for the default result size of 10
	var windowSize int64 = 10
	var rankConstant int64 = 42

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
			Field:         "text_embedding.predicted_value",
			K:             &amp;k,
			NumCandidates: &amp;numCandidates,
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).
		Query(&amp;types.Query{
			Match: map[string]types.MatchQuery{
				"title": {Query: term},
			},
		}).
		Rank(&amp;types.RankContainer{
			Rrf: &amp;types.RrfRank{
				WindowSize:   &amp;windowSize,
				RankConstant: &amp;rankConstant,
			},
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<h2>Conclusão</h2><p>Aqui discutimos como combinar a pesquisa vetorial e a pesquisa por palavra-chave no Elasticsearch usando o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>.</p><p>Confira o <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">repositório do GitHub</a> para acessar todo o código desta série. Caso ainda não tenha feito, confira <a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">a parte 1</a> e <a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">a parte 2</a> para ver todo o código desta série.</p><p><em>Boa caçada aos esquilos!</em></p><h2>Recursos</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Guia do Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Cliente Go do Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/what-is/vector-search">O que é busca vetorial? | Elástico</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">Fusão de Classificação Recíproca</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Banco de dados vetorial]]></category>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 02 Nov 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Realize buscas vetoriais no Elasticsearch com o cliente Elasticsearch Go.]]></title>
    <description><![CDATA[Aprenda como realizar buscas vetoriais no Elasticsearch usando o cliente Elasticsearch Go por meio de um exemplo prático.]]></description>
    <content:encoded><![CDATA[<p>Desenvolver software em qualquer linguagem de programação, incluindo Go, é comprometer-se com uma vida inteira de aprendizado. Ao longo de sua trajetória acadêmica e profissional, Carly explorou diversas linguagens de programação e tecnologias, incluindo as mais recentes e melhores implementações de busca vetorial. Mas isso não foi suficiente! Recentemente, Carly também começou a jogar Go.</p><p>Assim como os animais, as linguagens de programação e seu amigável autor, a busca passou por uma evolução de diferentes práticas, o que pode dificultar a escolha da melhor opção para o seu caso específico. Neste blog, compartilharemos uma visão geral da busca vetorial, juntamente com <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">exemplos</a> de cada abordagem usando <a href="https://www.elastic.co/elasticsearch/">o Elasticsearch</a> e o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>. Estes exemplos mostrarão como encontrar esquilos-da-terra e determinar o que eles comem usando a busca vetorial no Elasticsearch e em Go.</p><h2>Pré-requisitos</h2><p>Para dar continuidade a este exemplo, certifique-se de que os seguintes pré-requisitos sejam atendidos:</p><ol><li><p>Instalação do Go versão 1.21 ou posterior</p></li><li><p>Criação do seu próprio repositório Go com o</p></li><li><p>Criação do seu próprio cluster Elasticsearch, preenchido com um conjunto de páginas baseadas em roedores, incluindo para o nosso amigável <a href="https://en.wikipedia.org/wiki/Gopher">Gopher</a>, da Wikipédia:</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Página do Gopher na Wikipédia" /><h2>Conectando-se ao Elasticsearch</h2><p>Em nossos exemplos, utilizaremos a <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">API tipada</a> oferecida pelo cliente Go. Para estabelecer uma conexão segura para qualquer consulta, é necessário configurar o cliente usando um dos seguintes métodos:</p><ol><li><p>ID da nuvem e chave de API, caso esteja utilizando o Elastic Cloud.</p></li><li><p>URL do cluster, nome de usuário, senha e certificado.</p></li></ol><p>A conexão com nosso cluster localizado no Elastic Cloud seria feita da seguinte forma:</p>func GetElasticsearchClient() (*elasticsearch.TypedClient, error) {
	var cloudID = os.Getenv("ELASTIC_CLOUD_ID")
	var apiKey = os.Getenv("ELASTIC_API_KEY")

	var es, err = elasticsearch.NewTypedClient(elasticsearch.Config{
		CloudID: cloudID,
		APIKey:  apiKey,
		Logger:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

	if err != nil {
		return nil, fmt.Errorf("unable to connect: %w", err)
	}

	return es, nil
}
<p>A conexão <code>client</code> pode então ser usada para busca vetorial, como mostrado nas seções subsequentes.</p><h2>Busca vetorial</h2><p>A busca vetorial tenta resolver esse problema convertendo-o em uma comparação matemática usando vetores. O processo de incorporação de documentos possui uma etapa adicional de conversão do documento, utilizando um modelo, em uma representação vetorial densa, ou simplesmente em um fluxo de números. A vantagem dessa abordagem é que você pode pesquisar documentos não textuais, como imagens e áudio, convertendo-os em um vetor juntamente com uma consulta.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc4b3b9b2ad1e8f46/6a1704d06234e0800fdb1927/b113358093e367358d684f7aaf0a6684ebb2d0dd-1440x653.png" alt="Diagrama de Busca Vetorial" /><p>Em termos simples, a busca vetorial é um conjunto de cálculos de distância vetorial. Na ilustração abaixo, a representação vetorial da nossa consulta <code>Go Gopher</code>é comparada com os documentos no espaço vetorial, e os resultados mais próximos (denotados pela constante <code>k</code>) são retornados:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c736ecfc49bb038/6a1704d2cf4f25bcb6b2d075/54a17a4b41029644e7c66f33d428e8d01a6f4ce3-1184x743.png" alt="Exemplo de espaço vetorial Gopher" /><p>Dependendo da abordagem usada para gerar os embeddings dos seus documentos, existem duas maneiras diferentes de descobrir o que os gophers comem.</p><h3>Abordagem 1: Traga seu próprio modelo</h3><p>Com uma licença Platinum, é possível gerar os embeddings dentro do Elasticsearch, carregando o modelo e usando a API de inferência. A configuração do modelo envolve seis etapas:</p><ol><li><p>Selecione um modelo PyTorch para carregar a partir de um repositório de modelos. Neste exemplo, estamos usando o <a href="https://huggingface.co/sentence-transformers/msmarco-MiniLM-L-12-v3">sentence-transformers/msmarco-MiniLM-L-12-v3</a> da Hugging Face para gerar os embeddings.</p></li><li><p>Carregue o modelo no Elastic usando o <a href="https://www.elastic.co/guide/en/elasticsearch/client/eland/current/overview.html">cliente Eland Machine Learning para Python</a> usando as credenciais para nosso cluster Elasticsearch e tipo de tarefa <code>text_embeddings</code>. Se você não tiver o Eland instalado, poderá <a href="https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-import-model.html#ml-nlp-import-docker">executar a etapa de importação usando o Docker</a>, conforme mostrado abaixo:</p></li></ol>docker run -it --rm --network host \
    docker.elastic.co/eland/eland \
    eland_import_hub_model \
      --cloud-id $ELASTIC_CLOUD_ID \
      --es-api-key $ELASTIC_API_KEY \
      --hub-model-id sentence-transformers/msmarco-MiniLM-L-12-v3 \
      --task-type text_embedding
<ol><li><p>Após o carregamento, teste rapidamente o modelo <code>sentence-transformers__msmarco-minilm-l-12-v3</code> com um documento de exemplo para garantir que os embeddings sejam gerados conforme o esperado:</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a399e1f50ecfdaf/6a1704d4ab7f08935edb9d78/fbbdde621361a487eb07304bed029c228d0f7aa6-1440x789.png" alt="Exemplo de modelo treinado no Elastic Test" /><ol><li><p>Crie um pipeline de ingestão contendo um processador de inferência. Isso permitirá que a representação vetorial seja gerada usando o modelo carregado:</p></li></ol>PUT _ingest/pipeline/search-rodents-vector-embedding-pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
        "target_field": "text_embedding",
        "field_map": {
          "body_content": "text_field"
        }
      }
    }
  ]
}
<ol><li><p>Crie um novo índice contendo o campo <code>text_embedding.predicted_value</code> do tipo <code>dense_vector</code> para armazenar os vetores de incorporação gerados para cada documento:</p></li></ol>PUT vector-search-rodents
{
  "mappings": {
    "properties": {
      "text_embedding.predicted_value": {
        "type": "dense_vector",
        "dims": 384,
        "index": true,
        "similarity": "cosine"
      },
      "text": {
        "type": "text"
      }
    }
  }
}
<ol><li><p>Reindexe os documentos usando o pipeline de ingestão recém-criado para gerar os embeddings de texto como o campo adicional <code>text_embedding.predicted_value</code> em cada documento:</p></li></ol>POST _reindex
{
  "source": {
    "index": "search-rodents"
  },
  "dest": {
    "index": "vector-search-rodents",
    "pipeline": "search-rodents-vector-embedding-pipeline"
  }
}
<p>Agora podemos usar a opção <code>Knn</code> na mesma API de pesquisa usando o novo índice <code>vector-search-rodents</code>, como mostrado no exemplo abaixo:</p>func VectorSearch(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
  var k = 10
	var numCandidates = 10

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
      # Field in document containing vector
			Field:         "text_embedding.predicted_value",
      # Number of neighbors to return
			K:             &amp;k,
      # Number of candidates to evaluate in comparison
			NumCandidates: &amp;numCandidates,
      # Generate query vector using the same model used in the inference processor
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).Do(context.Background())

	if err != nil {
		return nil, fmt.Errorf("error in rodents vector search: %w", err)
	}

	return getRodents(res.Hits.Hits)
}
<p>A conversão do objeto JSON resultante por meio de desserialização é feita exatamente da mesma forma que no exemplo de pesquisa por palavra-chave. As constantes <code>K</code> e <code>NumCandidates</code> permitem configurar o número de documentos vizinhos a serem retornados e o número de candidatos a serem considerados por fragmento. Note que aumentar o número de candidatos aumenta a precisão dos resultados, mas leva a uma consulta mais demorada, pois mais comparações são realizadas.</p><p>Quando o código é executado usando a consulta <code>What do Gophers eat?</code>, os resultados retornados são semelhantes aos abaixo, destacando que o artigo do Gopher contém as informações solicitadas, diferentemente da pesquisa anterior por palavra-chave:</p>[
  {ID:64f74ecd4acb3df024d91112 Title:Gopher - Wikipedia Url:https://en.wikipedia.org/wiki/Gopher} 
  {ID:64f74ed34acb3d71aed91fcd Title:Squirrel - Wikipedia Url:https://en.wikipedia.org/wiki/Squirrel} 
  //Other results omitted
]
<h3>Abordagem 2: API de inferência do Hugging Face</h3><p>Outra opção é gerar esses mesmos embeddings fora do Elasticsearch e ingeri-los como parte do seu documento. Como essa opção não utiliza um nó de aprendizado de máquina do Elasticsearch, ela pode ser executada no nível gratuito.</p><p>A Hugging Face disponibiliza uma <a href="https://huggingface.co/docs/api-inference/index">API de inferência</a> gratuita e com limite de requisições que, mediante uma conta e um token de API, pode ser usada para gerar manualmente os mesmos embeddings para experimentação e prototipagem, ajudando você a começar. Não é recomendado para uso em produção. Invocar seus próprios modelos localmente para gerar embeddings ou usar a API paga também pode ser feito usando uma abordagem semelhante.</p><p>Na função abaixo <code>GetTextEmbeddingForQuery</code> usamos a API de inferência em nossa string de consulta para gerar o vetor retornado de uma solicitação <code>POST</code> ao endpoint:</p>// HuggingFace text embedding helper
func GetTextEmbeddingForQuery(term string) []float32 {
    // HTTP endpoint
    model := "sentence-transformers/msmarco-minilm-l-12-v3"
    posturl := fmt.Sprintf("https://api-inference.huggingface.co/pipeline/feature-extraction/%s", model)

    // JSON body
    body := []byte(fmt.Sprintf(`{
        "inputs": "%s",
        "options": {"wait_for_model":True}
    }`, term))

    // Create a HTTP post request
    r, err := http.NewRequest("POST", posturl, bytes.NewBuffer(body))

    if err != nil {
        log.Fatal(err)
        return nil
    }

    token := os.Getenv("HUGGING_FACE_TOKEN")
    r.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))

    client := &amp;http.Client{}
    res, err := client.Do(r)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()

    var post []float32
    derr := json.NewDecoder(res.Body).Decode(&amp;post)

    if derr != nil {
        log.Fatal(derr)
        return nil
    }

    return post
}
<p>O vetor resultante, do tipo <code>[]float32</code> é então passado como <code>QueryVector</code> em vez de usar a opção <code>QueryVectorBuilder</code> para aproveitar o modelo previamente carregado no Elastic.</p>func VectorSearchWithGeneratedQueryVector(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	vector, err := GetTextEmbeddingForQuery(term)
	if err != nil {
		return nil, err
	}

	if vector == nil {
		return nil, fmt.Errorf("unable to generate vector: %w", err)
	}

  var k = 10
	var numCandidates = 10

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
      # Field in document containing vector
			Field:         "text_embedding.predicted_value",
      # Number of neighbors to return
			K:             &amp;k,
      # Number of candidates to evaluate in comparison
			NumCandidates: &amp;numCandidates,
      # Query vector returned from Hugging Face inference API
			QueryVector:   vector,
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<p>Note que as opções <code>K</code> e <code>NumCandidates</code> permanecem as mesmas, independentemente das duas opções, e que os mesmos resultados são gerados, pois estamos usando o mesmo modelo para gerar os embeddings.</p><h2>Conclusão</h2><p>Aqui discutimos como realizar uma busca vetorial no Elasticsearch usando o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>. Confira o <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">repositório do GitHub</a> para acessar todo o código desta série. Continue para a <a href="https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client">parte 3</a> para obter uma visão geral da combinação da pesquisa vetorial com os recursos de pesquisa por palavra-chave abordados na <a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">parte 1</a> em Go.</p><p>Até lá, boa caçada aos esquilos!</p><h2>Recursos</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Guia do Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Cliente Go do Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/what-is/vector-search">O que é busca vetorial? | Elástico</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Banco de dados vetorial]]></category>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 01 Nov 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Execute consultas de texto com o cliente Elasticsearch Go.]]></title>
    <description><![CDATA[Aprenda como realizar consultas de texto tradicionais no Elasticsearch usando o cliente Elasticsearch Go por meio de um exemplo prático.]]></description>
    <content:encoded><![CDATA[<p>Desenvolver software em qualquer linguagem de programação, incluindo Go, é comprometer-se com uma vida inteira de aprendizado. Ao longo de sua trajetória universitária e profissional, Carly precisou se adaptar a ser poliglota e experimentar diversas linguagens de programação, incluindo Python, C, JavaScript, TypeScript e Java. Mas isso não foi suficiente! Recentemente, ela também começou a jogar Go!</p><p>Assim como os animais, as linguagens de programação e um de seus autores favoritos, a busca passou por uma evolução de diferentes práticas, o que pode dificultar a escolha da melhor opção para o seu caso específico. Neste blog, compartilharemos uma visão geral da pesquisa tradicional por palavras-chave, juntamente com <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">um exemplo</a> usando <a href="https://www.elastic.co/elasticsearch/">o Elasticsearch</a> e o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>.</p><h2>Pré-requisitos</h2><p>Para dar continuidade a este exemplo, certifique-se de que os seguintes pré-requisitos sejam atendidos:</p><ol><li><p>Instalação do Go versão 1.21 ou posterior</p></li><li><p>Crie seu próprio repositório Go usando a estrutura recomendada e o gerenciamento de pacotes abordados na <a href="https://go.dev/doc/code">documentação do Go.</a></p></li><li><p>Criação do seu próprio cluster Elasticsearch, preenchido com um conjunto de <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch#sources">páginas baseadas em roedores,</a> incluindo para o nosso amigável <a href="https://en.wikipedia.org/wiki/Gopher">Gopher</a>, da Wikipédia:</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Página do Gopher na Wikipédia" /><h2>Conectando-se ao Elasticsearch</h2><p>Em nossos exemplos, utilizaremos a <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">API tipada</a> oferecida pelo cliente Go. Para estabelecer uma conexão segura para qualquer consulta, é necessário configurar o cliente usando um dos seguintes métodos:</p><ol><li><p>ID da nuvem e chave de API, caso esteja utilizando o Elastic Cloud.</p></li><li><p>URL do cluster, nome de usuário, senha e certificado.</p></li></ol><p>A conexão com nosso cluster localizado no Elastic Cloud seria feita da seguinte forma:</p>func GetElasticsearchClient() (*elasticsearch.TypedClient, error) {
	var cloudID = os.Getenv("ELASTIC_CLOUD_ID")
	var apiKey = os.Getenv("ELASTIC_API_KEY")

	var es, err = elasticsearch.NewTypedClient(elasticsearch.Config{
		CloudID: cloudID,
		APIKey:  apiKey,
		Logger:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

	if err != nil {
		return nil, fmt.Errorf("unable to connect: %w", err)
	}

	return es, nil
}
<p>A conexão <code>client</code> pode então ser usada para pesquisa, como mostrado mais adiante.</p><h2>Pesquisa por palavra-chave</h2><p>A busca por palavras-chave é o tipo de busca fundamental com o qual estamos familiarizados desde a criação do <a href="https://en.wikipedia.org/wiki/Archie_(search_engine)">Archie</a>, o primeiro mecanismo de busca documentado na internet, escrito em 1990.</p><p>Um componente central da busca por palavras-chave é a tradução de documentos em um índice invertido. Assim como o índice encontrado no final de um livro didático, um índice invertido contém um mapeamento entre uma lista de palavras-chave e sua localização em cada documento. O diagrama abaixo mostra as principais etapas de geração do índice:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt366681a12027f14b/6a17e7aa1d1b831c2093e452/9cd7b2a60d9aa54facb37738b821bba6ca925830-1440x581.png" alt="Geração de Índice Invertido" /><p>Conforme mostrado acima, a geração de tokens no Elasticsearch compreende três etapas principais:</p><ol><li><p>Remoção de caracteres desnecessários através de zero ou mais <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-charfilters.html"><code>char_filters</code></a>. Em nosso exemplo, estamos removendo elementos HTML dentro do campo <code>body_content</code> através do filtro <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-htmlstrip-charfilter.html"><code>html_strip</code></a> .</p></li><li><p>Separando os tokens do conteúdo com o<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html"> tokenizador</a> <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html"><code>standard</code></a> , que irá separar por espaçamento e pontuação chave.</p></li><li><p>Remover tokens indesejados ou transformar tokens do fluxo de saída do tokenizador usando zero ou mais opções <code>filter</code> , como o<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html"> filtro de token</a> <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html"><code>lowercase</code></a>ou stemmers como o<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-snowball-tokenfilter.html"> stemmer</a> <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-snowball-tokenfilter.html"><code>snowball</code></a>para transformar tokens de volta à sua raiz de idioma.</p></li></ol><h2>Pesquisando no Elasticsearch com Go</h2><p>Ao realizar consultas com o cliente Go, especificamos o índice que desejamos pesquisar e passamos a consulta e outras opções, como no exemplo abaixo:</p>func KeywordSearch(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	res, err := client.Search().
		Index("search-rodents").
		Query(&amp;types.Query{
			Match: map[string]types.MatchQuery{
				"title": {Query: term},
			},
		}).
		From(0).
		Size(10).
		Do(context.Background())

	if err != nil {
		return nil, fmt.Errorf("could not search for rodents: %w", err)
	}

	return getRodents(res.Hits.Hits)
}
<p>No exemplo acima, realizamos uma<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html"> consulta</a> <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html"><code>match</code></a>padrão para encontrar qualquer documento em nosso índice que contenha a string especificada passada para nossa função. Observe que passamos um <a href="https://pkg.go.dev/context#Background">novo contexto vazio</a> para a execução da pesquisa por meio de <code>Do(context.Background())</code>. Além disso, quaisquer erros retornados pelo Elasticsearch são enviados para o atributo <code>err</code> para registro e tratamento de erros.</p><p>Os resultados são retornados em <code>res.Hits.Hits</code> com o atributo <code>_Source</code> contendo o próprio documento em formato JSON. Para converter essa fonte em uma estrutura compatível com Go, precisamos <a href="https://pkg.go.dev/encoding/json#Unmarshal">desserializar</a> a resposta JSON usando o <a href="https://pkg.go.dev/encoding/json">pacote `encoding/json`</a> do Go, como mostrado no exemplo abaixo:</p>func getRodents(hits []types.Hit) ([]Rodent, error) {
	var rodents []Rodent

	for _, hit := range hits {
		var currentRodent Rodent
		err := json.Unmarshal(hit.Source_, &amp;currentRodent)

		if err != nil {
			return nil, fmt.Errorf("an error occurred while unmarshaling rodent %s: %w", hit.Id_, err)
		}

		currentRodent.ID = hit.Id_
		rodents = append(rodents, currentRodent)
	}

	return rodents, nil
}
<p>A busca e a desserialização da consulta <code>gopher</code> retornarão a página da Wikipédia sobre Gopher, como esperado:</p>[
  {ID:64f74ecd4acb3df024d91112 Title:Gopher - Wikipedia Url:https://en.wikipedia.org/wiki/Gopher}
]
<p>No entanto, se consultarmos <code>What do Gophers eat?</code> , não obtemos exatamente os resultados que desejamos:</p>[]
<p>Uma simples busca por palavra-chave permite que os resultados sejam retornados ao seu aplicativo Go de forma eficiente e com a qual já estamos familiarizados a partir dos aplicativos que utilizamos. Também funciona muito bem para correspondências exatas de termos relevantes para cenários como a busca por uma empresa ou termo específico.</p><p>No entanto, como podemos ver acima, ele tem dificuldades em identificar o contexto e a semântica devido ao problema de incompatibilidade de vocabulário. Além disso, o suporte para formatos de arquivo não textuais, como imagens e áudio, é um desafio.</p><h2>Conclusão</h2><p>Aqui discutimos como realizar consultas de texto tradicionais no Elasticsearch usando o <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">cliente Elasticsearch Go</a>. Dado que o Go é amplamente utilizado para scripts de infraestrutura e construção de servidores web, é útil saber como pesquisar em Go.</p><p>Confira o <a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">repositório do GitHub</a> para acessar todo o código desta série. Continue para a <a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">parte 2</a> para obter uma visão geral da pesquisa vetorial e como realizar pesquisas vetoriais em Go. Até lá, boa caçada aos esquilos!</p><h2>Recursos</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Guia do Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Cliente Go do Elasticsearch</a></p></li><li><p><a href="https://codingexplained.com/coding/elasticsearch/understanding-analysis-in-elasticsearch-analyzers">Entendendo a Análise no Elasticsearch (Analisadores) por Bo Andersen | #CodingExplained</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 31 Oct 2023 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>