Pesquisa de texto completo
A pesquisa do Docsbook é um índice de texto completo do Postgres sobre suas páginas, exposto como um botão de pesquisa no cabeçalho e uma caixa de pesquisa na barra lateral. Ela não custa nada por consulta — nenhum modelo é chamado — e as consultas que não retornaram nada são um dos dois sinais mais úteis que sua documentação produz.
O que você obtém#
- Uma caixa de pesquisa no cabeçalho, na barra lateral ou em ambos. Ambos podem funcionar ao mesmo tempo; geralmente um é suficiente.
- Resultados com um trecho destacado — uma janela de contexto extraída do texto da página ao redor da correspondência, não dos primeiros 200 caracteres da página.
- Links diretos para o título exato. Uma correspondência dentro de uma seção mantém a âncora real dessa seção, para que o leitor chegue ao parágrafo em vez de ao topo de uma página longa.
- Páginas traduzidas primeiro. Se o leitor estiver em uma localidade traduzida, a linha traduzida terá prioridade; as páginas não traduzidas ainda aparecerão, para que um site parcialmente traduzido continue sendo pesquisado por inteiro.
- Um registro de todas as pesquisas que não retornaram nada, como um webhook
search.no_resultse um relatório de pesquisas sem resultados.
Como o índice é criado?#
Gravação durante a renderização, não no push. Uma página entra no índice quando o Docsbook a renderiza — depois que a resposta é enviada, para que a indexação nunca atrase a página. Uma página traduzida é indexada da mesma forma quando sua tradução é armazenada em cache. Não há nada para reconstruir manualmente nem botão de reindexação.
A consequência é importante: uma página que ninguém abriu desde que foi publicada ainda não está no índice. Portanto, um site recém-criado oferece poucos resultados de pesquisa até que suas páginas tenham sido visitadas pelo menos uma vez. Enquanto ainda não existir nenhuma linha, a caixa de pesquisa recorre à correspondência com os nomes de arquivo da lista de páginas, portanto nunca fica sem resultados.
O que entra em uma linha:
| Campo | Conteúdo |
|---|---|
| Título | title do frontmatter; caso contrário, o H1 da página; caso contrário, o nome do arquivo |
| Corpo | O texto simples da página: frontmatter, marcação de títulos, imagens, sintaxe de links, blocos de código delimitados e pontuação de markdown inline são removidos |
| Seções | Uma entrada por h2/h3, contendo a âncora renderizada do título e seu texto, com os blocos <pre> removidos |
| Idioma | Vazio para a página original; o código de localidade para cada tradução |
A pesquisa é executada sobre um tsvector gerado no qual o título tem peso A e o corpo tem peso B — os rótulos de peso do PostgreSQL existem para que "palavras de diferentes partes de um documento [possam ser] ponderadas de forma diferente pelas funções de classificação" (PostgreSQL: Recursos adicionais de pesquisa de texto). Essa coluna é indexada com GIN.
Como uma consulta é respondida?#
- As palavras de parada são removidas.
websearch_to_tsquery"combina termos de texto não citados com o operador&(AND)" (PostgreSQL: Controlando a pesquisa de texto), portanto uma frase completa exige que a página contenha também todas as palavras de preenchimento. Uma lista de 45 palavras de parada em inglês é removida primeiro, somente fora das aspas — assim,"exact phrase",ORe-wordcontinuam funcionando. - As consultas em inglês passam por stemming. Para conteúdo em inglês e não traduzido, a consulta e o documento são comparados usando a configuração
english, que utiliza um stemmer Snowball que "reduz formas variantes comuns das palavras a uma grafia base, ou radical" (PostgreSQL: Dicionários). Sem isso, uma página que diz "served" não corresponde a uma consulta que diz "serve". - Outros idiomas usam o índice armazenado. Locales que não são ingleses fazem a correspondência com o vetor
simplearmazenado, que "funciona convertendo o token de entrada para letras minúsculas" e não aplica stemming. Aplicar regras de stemming do inglês a textos não latinos produz resultados sem sentido, portanto elas não são aplicadas deliberadamente. - O caminho em inglês normaliza a classificação de acordo com o comprimento. Em consultas em inglês,
ts_ranké executado com o sinalizador de normalização 1, que "divide a classificação por 1 + o logaritmo do comprimento do documento". Sem isso, um changelog de 76 KB que menciona todos os termos da consulta de passagem supera a página curta que realmente trata da pergunta. O caminho para outros idiomas chamats_ranksem sinalizador de normalização, portanto, nesses locales, uma página longa não é penalizada por seu comprimento — consulte Limites. - Uma linha por página. O original e a tradução são consolidados em um único resultado, priorizando o idioma do leitor e, em seguida, a classificação. Uma ocorrência no título é promovida acima das ocorrências apenas no corpo.
- O trecho é gerado no servidor.
ts_headlineretorna um fragmento de 5–18 palavras ao redor da correspondência; o cliente realça novamente os termos.
O que acontece com um erro de digitação?#
Nada corresponde. A pesquisa do Docsbook não usa correspondência aproximada, similaridade de trigramas nem fallback de distância de edição. A derivação cobre flexões — serve encontra served — mas não erros de ortografia: documnetation não encontra nada.
Essa é uma escolha deliberada, não uma falha, e vem acompanhada de um mecanismo compensatório: toda consulta sem resultados é informada a você. O relatório é agrupado para que uma busca gere um sinal, e não um por tecla pressionada:
- O navegador espera 1,5 segundo depois que o leitor para de digitar antes de informar uma falha e envia imediatamente se ele fechar a caixa de diálogo no meio da busca — medido em um espaço de trabalho ativo, um leitor digitando uma palavra fez pausas de 0,9–1,3 s entre os caracteres, o que produziu oito relatórios para uma palavra antes disso existir.
- O servidor suprime independentemente uma falha que seja uma extensão de prefixo estrita da anterior do mesmo leitor dentro de uma janela curta, porque o endpoint é público e não pode presumir que algum cliente tenha aplicado debounce.
Portanto, documnetation chegar ao seu relatório de pesquisas malsucedidas não é um erro na pesquisa — é a pesquisa informando que um leitor não conseguiu encontrar a página, e é nisso que você deve agir. Erros de ortografia recorrentes são melhor corrigidos no seu conteúdo, nomeando o termo que o leitor realmente digita.
Onde a caixa de pesquisa fica#
| Posicionamento | Ideal para | Desvantagem |
|---|---|---|
| Botão no cabeçalho | Visitantes de primeira viagem, que olham primeiro para a barra superior | Disputa espaço com os links do cabeçalho |
| Caixa na barra lateral | Leitores que já navegam pela árvore | Fica oculta em telas estreitas, onde a barra lateral é recolhida |
Ative o botão no cabeçalho em Widget flutuante → Design → Cabeçalho → Botão de pesquisa. Ative a caixa na barra lateral em Widget flutuante → Design → Barra lateral esquerda → Pesquisar na barra lateral. Ambos são gratuitos em todos os planos.
Por que esta é a maneira certa (evidências)#
| Regra | Por que funciona | Fonte |
|---|---|---|
| Mantenha um índice lexical mesmo com a pesquisa semântica disponível | Em mais de 18 conjuntos de dados de recuperação, "BM25 é uma linha de base robusta" em configurações zero-shot, enquanto os recuperadores densos "frequentemente têm desempenho inferior" — seu corpus está fora do domínio de qualquer modelo de embeddings, e os termos exatos são o que os leitores técnicos digitam | Thakur et al., 2021 — BEIR |
| Remova as stopwords antes que a consulta chegue ao Postgres | websearch_to_tsquery faz AND entre termos não citados, portanto uma palavra de preenchimento ausente da página faz com que toda a correspondência falhe |
PostgreSQL: Controle da pesquisa de texto |
| Faça stemming em inglês, mas não em outros idiomas | A configuração simple apenas converte para minúsculas; os stemmers Snowball são específicos para cada idioma e reduzem as variantes a um radical |
PostgreSQL: Dicionários |
| Normalize a classificação pelo tamanho do documento (caminho em inglês) | O sinalizador 1 "divide a classificação por 1 + o logaritmo do tamanho do documento", portanto uma menção incidental longa não pode superar uma página curta sobre o tópico | PostgreSQL: Controle da pesquisa de texto |
| Dê mais peso ao título do que ao corpo | Os rótulos de peso permitem que a classificação trate de forma diferente as palavras de diferentes partes de um documento | PostgreSQL: Recursos adicionais de pesquisa de texto |
O mesmo índice é um dos dois recuperadores por trás do chat de IA — ele também não é um recurso alternativo inferior nesse caso.
Limites#
- Nenhuma tolerância a erros de digitação. Veja acima. Se uma grafia incorreta for importante para o seu público, adicione o termo à página.
- Blocos de código não são pesquisáveis. O código cercado é removido antes da indexação, e os blocos
<pre>são removidos do texto da seção. Um leitor que pesquisar o nome de uma função que aparece apenas dentro de um exemplo de código não o encontrará. Há uma questão aqui: a documentação antiga afirmava que os blocos de código eram indexados e "classificados abaixo do texto corrido"; o indexador os remove completamente. - A cobertura depende do tráfego, não do seu repositório. Uma página entra no índice na sua primeira renderização. Uma página publicada, mas nunca aberta, fica ausente dos resultados de pesquisa até que alguém a abra.
- Não publicamos nenhum número de latência. As consultas em inglês calculam seu
tsvectorno momento da consulta, em vez de ler o índicesimplearmazenado, o que significa que o caminho em inglês realiza mais trabalho por consulta à medida que o corpus cresce. Não publicamos um benchmark e não citaremos um até que tenhamos um. - A normalização do comprimento é exclusiva do inglês. O caminho de consulta em inglês passa a flag de normalização 1 para
ts_rank; o caminho usado para outras localidades chamats_ranksem nenhuma flag, o que significa que não há normalização de comprimento. Em um site que não esteja em inglês, uma página muito longa pode, portanto, superar uma página curta que seja mais precisamente relacionada à consulta. Isso permanece em aberto até que os dois caminhos sejam reconciliados. - A pesquisa é feita por projeto. O índice é restrito a um único espaço de trabalho; não há pesquisa entre projetos.
- O sinal de pesquisa sem resultados é agrupado, não exato. O primeiro resultado ausente de uma sequência de digitação é o que é enviado a um webhook ativo, portanto a consulta enviada pode ser um prefixo mais curto daquela que o leitor acabou inserindo. O relatório histórico recupera a consulta final.
Relacionado#
- Chat de IA — o assistente que usa este índice como um dos seus recuperadores.
- Qualidade das respostas — como a recuperação lexical e vetorial são combinadas.
- Análises: o que os leitores pesquisaram — as consultas que não retornaram nada.
- Feedback da página — o outro sinal de que uma página está ausente ou tem um nome incorreto.