Pular para o conteúdo principal

Busca híbrida: combinando consultas por vetores e palavras-chave no MongoDB

Aprenda o que é busca híbrida e como usá-la no MongoDB.
Atualizado 17 de set. de 2026  · 6 min lido

Explorar com IA

ChatGPTClaudePerplexity

Às vezes, só a busca por texto completo ou apenas a busca vetorial não bastam para consultar um banco de dados e encontrar exatamente o que você procura. A combinação das duas é ótima quando o desenvolvedor lida com grandes volumes de dados multimodais e não estruturados que se beneficiam dos dois tipos de busca. Isso é a chamada busca híbrida — uma solução e tanto para um desafio complexo. 

O que exatamente é busca híbrida? 

Para entender bem a busca híbrida, primeiro precisamos entender o que é a busca por texto completo. 

Busca por texto completo é um modo de pesquisa que casa termos literais da sua consulta com os documentos. Esse tipo de busca tradicional é, na verdade, o que muitos desenvolvedores já conhecem bem.

Por exemplo, se você procurar por “cafeteria fofa com área externa”, o mecanismo de busca vai procurar essas palavras exatas no banco de dados. Em resumo, a busca por texto completo é super precisa e eficiente, mas não funciona tão bem se você quiser resultados semelhantes usando sinônimos, paráfrases ou até quando há um erro de digitação na consulta. 

Já a busca vetorial converte todos os dados em números, ou embeddings. Em vez de bater palavra por palavra, a busca vetorial compara o significado semântico da sua consulta com os documentos armazenados no banco. 

Buscar por “cafeteria fofa com área externa” pode trazer “pães e café do lado de fora”, mesmo sem usar as mesmas palavras. A busca vetorial não é só semântica; ela também é muito flexível, mas às vezes pode retornar resultados amplos demais para a consulta especificada. 

E onde entra a busca híbrida? Ela combina a busca por texto completo com a busca vetorial. Assim, os desenvolvedores aproveitam tanto a inteligência semântica dos vetores quanto os filtros precisos da busca por texto completo. É o melhor dos dois mundos — e muito útil ao trabalhar com grandes conjuntos de dados não estruturados. 

Por que a busca híbrida é importante 

A busca híbrida é valiosa em várias aplicações reais, como e-commerce, saúde e até recrutamento, entre outras. 

No e-commerce, imagine entrar no seu site favorito e procurar por “cadeira de escritório confortável até US$ 100”. Com a busca vetorial, você verá itens semanticamente parecidos (como cadeiras ergonômicas), enquanto a busca por texto completo foca na palavra “cadeira” e ajuda a reforçar o teto de preço. 

No recrutamento, se um recrutador busca em currículos por “engenheiro com experiência em NLP”, a busca híbrida captura tanto “processamento de linguagem natural” quanto a palavra-chave exata “engenheiro”.

Ou seja: você recebe resultados mais relevantes e confiáveis do que usando qualquer uma das abordagens isoladamente. 

Busca híbrida no MongoDB

Vamos ver como fazer busca híbrida no MongoDB Atlas. Para acompanhar este tutorial, você vai precisar de alguns pré-requisitos: 

  1. Uma conta no MongoDB Atlas  
  2. Um cluster free tier do MongoDB Atlas
  3. mongosh instalado no seu terminal

Neste tutorial, vamos focar na coleção embedded movies no nosso banco de dados sample_mflix, acompanhando este tutorial de busca híbrida com $rankFusion, com alguns ajustes. 

Embora o novo operador $rankFusion esteja disponível em clusters a partir da versão 8.1+ e facilite muito a busca híbrida no MongoDB, ele ainda está em Public Preview — e clusters do free tier ficam automaticamente na versão 8.0. Então, vamos seguir o tutorial, fazer algumas mudanças e concluir com tudo.

Providencie seu cluster

Ao criar o cluster, garanta que você está baixando o dataset sample_mflix. É com ele que vamos trabalhar durante todo o tutorial, focando na coleção sample_mflix.embedded_movies

Confira rapidamente se o mongosh está instalado.

mongosh --version

Para este tutorial, estou usando a versão 2.4.2. 

Agora, conecte-se ao seu cluster do MongoDB Atlas:

mongosh "mongodb+srv://<yourclusterhere>.mongodb.net/" --apiVersion 1 --username <yourusername> 

O terminal vai pedir a senha e, depois de conectado, a saída será algo assim:

Agora podemos nos conectar ao banco. Rode o comando:

use sample_mflix

A saída será: 

switched to db sample_mflix

Crie seus índices

Vamos criar os dois índices necessários para este tutorial: o índice vetorial e o índice de busca por texto completo. Lembre que estamos criando ambos na coleção embedded_movies

Índice vetorial:

db.embedded_movies.createSearchIndex(
  "hybrid-vector-search",
  "vectorSearch",
  {
    fields: [
      { type: "vector", path: "plot_embedding_voyage_3_large", numDimensions: 2048, similarity: "dotProduct" }
    ]
  }
)

Índice de texto completo:

db.embedded_movies.createSearchIndex(
  "hybrid-full-text-search",
  "search",
  { mappings: { dynamic: true } }
)

Confira no seu cluster do MongoDB Atlas se os índices estão prontos:

Consulte o banco

Agora vamos consultar os dados da coleção sample_mflix.embedded_movies por “star wars” no campo plot_embedding_voyage_3_large

Seguindo o tutorial, como não vamos usar nenhuma API, podemos salvar todos os embeddings necessários em um arquivo separado chamado query_embeddings.js

Agora podemos carregar os embeddings para usar na consulta. Rode:

load('/Users/<PATH NAME>/query_embeddings.js')
const queryVec = STAR_WARS_EMBEDDING

Para garantir que os embeddings foram carregados, rode:

STAR_WARS_EMBEDDING.length

Uma saída 2048 está correta. 

Pipeline de agregação

Agora vamos criar um pipeline de agregação para a busca híbrida. Vale lembrar que há algumas limitações e motivos para estruturarmos o pipeline desta forma. 

Como dissemos acima, embora exista o $rankFusion no MongoDB Atlas, ele está em Public Preview e você precisa de um cluster 8.0 ou superior. No free tier, você não pode usar o $rankFusion por enquanto. Isso complica um pouco, pois o Atlas não fará a fusão nativa dos rankings de texto e vetor. Então temos que fazer nossa própria fusão — uma mescla ponderada das duas listas ranqueadas. 

As posições das stages no pipeline de agregação também são rígidas:

  • $search precisa ser a primeira stage do pipeline. 
  • $vectorSearch tem que iniciar o pipeline e não pode estar dentro de $facet.

Qual o workaround? $vectorSearch pode ser a primeira stage de um subpipeline dentro de $unionWith, já que esse subpipeline é tratado como um pipeline à parte. 

Por isso, começamos com $search para os resultados de texto completo manterem sua pontuação e, em seguida, usamos $unionWith como um mini-pipeline que inicia com $vectorSearch para também preservar sua pontuação. 

Depois, agrupamos por _id para evitar duplicados e aproveitar o melhor de cada um dos termos de $search e $vectorSearch

Feito isso, calculamos a busca híbrida: pegamos o melhor de $search, o melhor de $vectorSearch, multiplicamos por um peso à nossa escolha (usei 0,35) e ordenamos a partir daí. 

O peso define quanto a busca vetorial influencia em relação à busca por texto completo no resultado final. 

Nossa fórmula híbrida é: hybrid_score = text_score + (vector_score x weight). Um peso maior (ex.: 0,7–1,0) faz a busca vetorial dominar, priorizando similaridade semântica. 

Um peso menor (0,1–0,3), por outro lado, faz a busca por texto completo dominar, priorizando correspondências exatas de palavras-chave. 

Copie e cole este pipeline de agregação no seu terminal:

const WEIGHT = 0.35;

db.embedded_movies.aggregate([
// Stage 1: full-text search
  { $search: { index: "hybrid-full-text-search", text: { query: "star wars", path: ["title","plot"] } } },
  { $set: { t: { $meta: "searchScore" } } },
  { $project: { _id: 1, title: 1, plot: 1, t: 1 } },
// Stage 2: Union with vector search
  { $unionWith: {
      coll: "embedded_movies",
      pipeline: [
// Vector search subpipeline
        { $vectorSearch: {
            index: "hybrid-vector-search",
            path: "plot_embedding_voyage_3_large",
            queryVector: queryVec,
            numCandidates: 200,
            limit: 150
        }},
        { $project: { _id: 1, title: 1, plot: 1, v: { $meta: "vectorSearchScore" } } }
      ]
  }},
// Stage 3: Combine and rank results
  { $group: { _id: "$_id", title: { $first: "$title" }, plot: { $first: "$plot" }, t: { $max: "$t" }, v: { $max: "$v" } } },
  { $set: { h: { $add: [ { $ifNull: ["$t", 0] }, { $multiply: [ { $ifNull: ["$v", 0] }, WEIGHT ] } ] } } },
  { $sort: { h: -1 } },
  { $limit: 20 }
]).toArray()

Aqui está a nossa saída:

  {
    _id: ObjectId('573a139af29313caabcf124d'),
    title: 'Star Wars: Episode III - Revenge of the Sith',
    plot: 'As the Clone Wars near an end, the Sith Lord Darth Sidious steps out of the shadows, at which time Anakin succumbs to his emotions, becoming Darth Vader and putting his relationships with Obi-Wan and Padme at risk.',
    t: 4.957413673400879,
    v: 0.756283700466156,
    h: 5.2221129685640335
  },
  {
    _id: ObjectId('573a13a6f29313caabd17d08'),
    title: 'Star',
    plot: 'The Driver now carries an arrogant rock star who is visiting a major city (not Pittsburgh as earlier believed). Played by Madonna, this title character wants to get away from her bodyguards...',
    t: 5.151784420013428,
    v: null,
    h: 5.151784420013428
  },
  {
    _id: ObjectId('573a1397f29313caabce8cdb'),
    title: 'Star Wars: Episode VI - Return of the Jedi',
    plot: 'After rescuing Han Solo from the palace of Jabba the Hutt, the rebels attempt to destroy the second Death Star, while Luke struggles to make Vader return from the dark side of the Force.',
    t: 4.726564407348633,
    v: 0.7782549858093262,
    h: 4.998953652381897
  },
  {
    _id: ObjectId('573a13aef29313caabd2da15'),
    title: 'Star Runner',
    plot: 'Get ready for the ultimate martial arts competition, where anything goes and lives are bought and sold. Tank is the celebrated Champion Star Runner and is deemed invincible among the ...',
    t: 4.702453136444092,
    v: 0.696668267250061,
    h: 4.9462870299816135
  },
  {
    _id: ObjectId('573a13c0f29313caabd62f62'),
    title: 'Star Wars: The Clone Wars',
    plot: 'Anakin Skywalker and Ahsoka Tano must rescue the kidnapped son of Jabba the Hutt, but political intrigue complicates their mission.',
    t: 4.537533760070801,
    v: 0.7561323642730713,
    h: 4.802180087566375
  },
  {
    _id: ObjectId('573a1397f29313caabce6f53'),
    title: 'Message from Space',
    plot: 'In this Star Wars take-off, the peaceful planet of Jillucia has been nearly wiped out by the Gavanas, whose leader takes orders from his mother (played a comic actor in drag) rather than ...',
    t: 4.401333808898926,
    v: 0.7913960218429565,
    h: 4.678322416543961
  },
  {
    _id: ObjectId('573a139df29313caabcfa90b'),
    title: 'Message from Space',
    plot: 'In this Star Wars take-off, the peaceful planet of Jillucia has been nearly wiped out by the Gavanas, whose leader takes orders from his mother (played a comic actor in drag) rather than ...',
    t: 4.401333808898926,
    v: 0.7913960218429565,
    h: 4.678322416543961
  },
  {
    _id: ObjectId('573a1398f29313caabce9851'),
    title: 'Gymkata',
    plot: 'Johnathan Cabot is a champion gymnast. In the tiny, yet savage, country of Parmistan, there is a perfect spot for a "star wars" site. For the US to get this site, they must compete in the ...',
    t: 4.284864902496338,
    v: 0.7193170189857483,
    h: 4.53662585914135
  },
  {
    _id: ObjectId('573a1397f29313caabce68f6'),
    title: 'Star Wars: Episode IV - A New Hope',
    plot: "Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a wookiee and two droids to save the universe from the Empire's world-destroying battle-station, while also attempting to rescue Princess Leia from the evil Darth Vader.",
    t: 2.9629626274108887,
    v: 0.7987099885940552,
    h: 3.242511123418808
  },
  {
    _id: ObjectId('573a139af29313caabcf0f5f'),
    title: 'Star Wars: Episode I - The Phantom Menace',
    plot: 'Two Jedi Knights escape a hostile blockade to find allies and come across a young boy who may bring balance to the Force, but the long dormant Sith resurface to reclaim their old glory.',
    t: 2.9629626274108887,
    v: 0.7771433591842651,
    h: 3.2349628031253816
  },
  {
    _id: ObjectId('573a1397f29313caabce77d9'),
    title: 'Star Wars: Episode V - The Empire Strikes Back',
    plot: 'After the rebels have been brutally overpowered by the Empire on their newly established base, Luke Skywalker takes advanced Jedi training with Master Yoda, while his friends are pursued by Darth Vader as part of his plan to capture Luke.',
    t: 2.7174296379089355,
    v: 0.7810181975364685,
    h: 2.9907860070466996
  },
  {
    _id: ObjectId('573a139af29313caabcf1258'),
    title: 'Star Wars: Episode II - Attack of the Clones',
    plot: 'Ten years after initially meeting, Anakin Skywalker shares a forbidden romance with Padmè, while Obi-Wan investigates an assassination attempt on the Senator and discovers a secret clone army crafted for the Jedi.',
    t: 2.7174296379089355,
    v: 0.7400004267692566,
    h: 2.9764297872781755
  },
  {
    _id: ObjectId('573a1394f29313caabcdf65b'),
    title: 'Ugetsu',
    plot: 'A fantastic tale of war, love, family and ambition set in the midst of the Japanese Civil Wars of the sixteenth century.',
    t: 2.858368396759033,
    v: null,
    h: 2.858368396759033
  },
  {
    _id: ObjectId('573a13a4f29313caabd1137f'),
    title: 'S1m0ne',
    plot: "A producer's film is endangered when his star walks off, so he decides to digitally create an actress to substitute for the star, becoming an overnight sensation that everyone thinks is a real person.",
    t: 2.842216730117798,
    v: null,
    h: 2.842216730117798
  },
  {
    _id: ObjectId('573a13b8f29313caabd4c3c3'),
    title: 'Star Trek',
    plot: "The brash James T. Kirk tries to live up to his father's legacy with Mr. Spock keeping him in check as a vengeful, time-traveling Romulan creates black holes to destroy the Federation one planet at a time.",
    t: 2.577816963195801,
    v: 0.7295459508895874,
    h: 2.8331580460071564
  },
  {
    _id: ObjectId('573a13b5f29313caabd42e99'),
    title: 'Sars Wars',
    plot: "The fourth generation of the virus SARS is found in Africa! It's more dangerous and causes the patients to transform into bloodthirsty zombies. The virus quickly lands to Thailand, Dr. ...",
    t: 2.826810598373413,
    v: null,
    h: 2.826810598373413
  },
  {
    _id: ObjectId('573a13b5f29313caabd42e1b'),
    title: 'Sars Wars',
    plot: "The fourth generation of the virus SARS is found in Africa! It's more dangerous and causes the patients to transform into bloodthirsty zombies. The virus quickly lands to Thailand, Dr. ...",
    t: 2.826810598373413,
    v: null,
    h: 2.826810598373413
  }

Como podemos ver, temos alguns resultados idênticos à nossa consulta, “star wars”, e outros resultados que claramente não têm a ver com o significado.

Conclusão 

Parabéns! Você concluiu com sucesso a busca híbrida no MongoDB. Embora o $rankFusion simplifique esse processo, este método mostra um workaround enquanto o operador ainda está em Public Preview. Com este tutorial, incorporamos com sucesso a busca por texto completo e a busca vetorial em um único pipeline para recuperar os resultados mais otimizados para nossa consulta. Para mais informações sobre busca híbrida no MongoDB, consulte a documentação do MongoDB. Se você ainda está se familiarizando com o MongoDB, recomendo o curso Introdução ao MongoDB em Python.

Perguntas frequentes sobre busca híbrida no MongoDB

Preciso do MongoDB 8.1 e do $rankFusion para fazer busca híbrida?

Não. Na versão 8.0, você pode fundir as pontuações manualmente. Faça isso rodando $search e $vectorSearch em dois pipelines e combinando-os com $unionWith + $group e uma fórmula ponderada. Na versão 8.1+, o $rankFusion fará isso para você.

O que é busca híbrida?

É a combinação da busca por texto completo (palavras exatas) e busca vetorial (significado) para obter os resultados mais otimizados possíveis para uma determinada consulta.

Quando devo usar a busca híbrida?

Use a busca híbrida quando seu texto for variado (sinônimos, paráfrases, erros de digitação), mas você ainda quiser termos exatos.

Como escolho o peso que quero usar?

A melhor prática é começar em torno de 0,2–0,5. Valores menores dão mais influência à busca por texto completo, e valores maiores dão mais influência à semântica. É importante ajustar o peso após testar e visualizar os resultados obtidos.

A busca híbrida funciona com dados de imagem e áudio?

Sim! Desde que seus dados possam ser transformados em embeddings vetoriais e você possa combiná-los com restrições de palavras específicas, você pode realizar busca híbrida em um dataset.

Tópicos
MongoDB
Bancos de dados vetoriais

Principais cursos do DataCamp

Curso

Introdução ao MongoDB em Python

3 h
24.3K
Aprenda a mexer e analisar dados estruturados de forma flexível com o MongoDB.
Ver detalhesRight Arrow
Iniciar Curso
Ver maisRight Arrow
Relacionado

blog

Os 7 melhores bancos de dados vetoriais em 2026

Um guia completo com os melhores bancos de dados vetoriais. Domine o armazenamento de dados de alta dimensão, decifrar informações não estruturadas e aproveitar as incorporações vetoriais para aplicações de IA.
Moez Ali's photo

Moez Ali

14 min

blog

Bancos de dados NoSQL: O que todo cientista de dados precisa saber

Descubra para que servem os bancos de dados NoSQL, por que os cientistas de dados os utilizam e uma lista dos melhores bancos de dados NoSQL disponíveis.
Zoumana Keita 's photo

Zoumana Keita

12 min

blog

O que são embeddings vetoriais? Uma explicação intuitiva

As incorporações de vetores são representações numéricas de palavras ou frases que capturam seus significados e relacionamentos, ajudando os modelos de machine learning a entender o texto com mais eficiência.

Tutorial

Tutorial pgvector: Integrar a Pesquisa Vetorial no PostgreSQL

Descubra como melhorar o PostgreSQL com recursos de pesquisa vetorial usando o pgvector. Este tutorial te mostra como instalar, usar as funções básicas e integrar com ferramentas de IA.
Moez Ali's photo

Moez Ali

10 min

Tutorial

Como usar GROUP BY e HAVING no SQL

Um guia intuitivo para você descobrir os dois comandos SQL mais populares para agregar linhas do seu conjunto de dados
Eugenia Anello's photo

Eugenia Anello

6 min

Tutorial

Tutorial do Chroma DB: Um guia passo a passo

Com o Chroma DB, você pode gerenciar facilmente documentos de texto, converter texto em embeddings e fazer pesquisas de similaridade.
Abid Ali Awan's photo

Abid Ali Awan

10 min

Ver MaisVer Mais