1 pontos por GN⁺ 2024-05-28 | 1 comentários | Compartilhar no WhatsApp
  • Tantivy é uma biblioteca rápida de mecanismo de busca full-text escrita em Rust e está mais próxima de um crate usado para criar mecanismos de busca do que de um servidor de busca completo
  • Seu design foi fortemente inspirado no Apache Lucene e, caso você esteja procurando um servidor alternativo ao Elasticsearch ou Apache Solr, a recomendação é conferir o mecanismo de busca distribuído Quickwit, construído sobre o Tantivy
  • Os recursos incluem busca full-text, pontuação BM25, consultas em linguagem natural, busca por frase, indexação incremental, indexação multithread, diretório mmap, compressão de inteiros com SIMD, busca por facetas, campos JSON e coletores de agregação
  • Funciona em Rust estável, oferece suporte a Linux, macOS e Windows, e informa ter tempo de inicialização inferior a 10 ms, o que o torna adequado para ferramentas de linha de comando
  • Busca distribuída está fora do escopo do Tantivy; para modificar documentos, é preciso excluir o documento existente e indexá-lo novamente; novos documentos só podem ser pesquisados após commit, recarregar o IndexReader e obter um novo Searcher

Posição e design do Tantivy

  • Tantivy é uma biblioteca rápida de mecanismo de busca full-text escrita em Rust
  • Não é um servidor de busca pronto para executar como Elasticsearch ou Apache Solr, mas sim um crate que pode ser usado para criar esse tipo de mecanismo de busca
  • Em termos de design, está mais próximo do Apache Lucene e foi fortemente inspirado por sua arquitetura
  • Se você procura uma alternativa ao Elasticsearch ou Apache Solr, a recomendação é conferir o mecanismo de busca distribuído Quickwit, construído sobre o Tantivy

Desempenho e benchmarks

  • O Tantivy fornece benchmarks separados por tipo de consulta e tipo de coleção
  • Os resultados dos benchmarks podem variar conforme a natureza da consulta e a carga
  • Os detalhes dos benchmarks podem ser consultados no repositório search-benchmark-game
  • Segundo o FAQ, em benchmarks de latência de busca, o Tantivy é em média cerca de 2 vezes mais rápido que o Lucene

Recursos de busca e indexação

  • Recursos de busca

    • Busca full-text
    • Pontuação BM25 como no Lucene
    • Suporte a consultas em linguagem natural: (michael AND jackson) OR "king of pop"
    • Suporte a busca por frase: "michael jackson"
    • Consultas por intervalo
    • Busca por facetas
    • Campo JSON
    • Aggregation Collector: histogram, range buckets, average, stats metrics
  • Recursos de indexação

    • Suporte a indexação incremental
    • Suporte a indexação multithread
    • Informa que a indexação da Wikipedia em inglês leva menos de 3 minutos em um desktop
    • Permite configurar a indexação com term frequency e position indexing opcionais
    • Suporte a LogMergePolicy with deletes
    • Fornece API de Searcher Warmer
  • Armazenamento e campos

    • Suporte a diretório mmap
    • Suporte a fast fields single-valued e multivalued de u64, i64 e f64
    • Suporte a fast fields &[u8]
    • Suporte a campos text, i64, u64, f64, dates, ip, bool e hierarchical facet
    • A compressão do armazenamento de documentos oferece suporte a LZ4, Zstd e None

Tokenizer e suporte a idiomas

Ambiente de execução e como começar

  • O Tantivy funciona em stable Rust
  • Os sistemas operacionais suportados são Linux, macOS e Windows
  • O tempo de inicialização é inferior a 10 ms, o que o torna adequado para ferramentas de linha de comando
  • Materiais para começar
  • O build e os testes locais podem ser executados com os seguintes comandos
git clone https://github.com/quickwit-oss/tantivy.git
cd tantivy
cargo test

Recursos fora do escopo e modelo de alteração de dados

  • Busca distribuída está fora do escopo do Tantivy
  • Se precisar de busca distribuída, a recomendação é conferir o Quickwit
  • Os dados do Tantivy são imutáveis
  • Para modificar um documento, é preciso excluir o documento existente e indexá-lo novamente
  • Documentos em indexação só podem ser pesquisados depois que commit é chamado no IndexWriter
  • O IndexReader existente precisa ser recarregado para refletir as mudanças
  • As mudanças só ficam visíveis em um Searcher recém-obtido

Bindings e casos de uso

  • Bindings disponíveis para uso em outras linguagens
    • Python: tantivy-py
    • Ruby: tantiny
    • Outros bindings também podem ser encontrados no GitHub, mas podem ter manutenção menos ativa
  • Exemplos de uso do Tantivy
    • seshat: banco de dados/indexador de mensagens do Matrix
    • tantiny: pequena busca full-text para Ruby
    • lnx: mecanismo de busca adaptativo tolerante a erros de digitação com API REST
    • Bichon: arquivador de e-mails em Rust leve e de alto desempenho com WebUI
  • As empresas listadas como usuárias do Tantivy incluem Etsy, ParadeDB, Nuclia, Humanfirst.ai e Element.io

1 comentários

 
GN⁺ 2024-05-28
Opiniões do Hacker News
  • As pessoas que criaram esta biblioteca são realmente incríveis. No ano passado, ao substituir uma base de código antiga em Python2 no AppEngine que eu tinha deixado abandonada por muito tempo, refiz https://progscrape.com [1] em cima dela; é uma biblioteca excelente e absurdamente rápida
    A ponto de indexar 1 milhão de histórias inteiras em poucos segundos em um Raspberry Pi
    Rodo um serviço de busca full-text no Pi de casa e, embora o pico de carga seja baixo, de alguns rps, a CPU quase nunca passa de alguns por cento. Fiz teste de carga de busca no Pi até cerca de 100 rps e ele aguentou. Foi uma biblioteca muito útil, que deu para encaixar praticamente direto; a equipe também respondeu muito rápido aos relatórios de bug, e havia pouquíssimos bugs
    Para ver como a busca responde nesse dispositivo pequeno, é só clicar nos rótulos de cada história. As consultas são praticamente instantâneas, atingindo até 10 anos * 12 meses de shards de busca: https://progscrape.com/?search=javascript
    Para um projeto moderno, recomendo olhar isso em vez do Lucene. Se escala tão bem até em um ARM64 pequeno, há grande chance de a experiência ser muito melhor em servidores maiores
    [1] https://github.com/progscrape/progscrape

    • É uma biblioteca muito boa. Estou usando em uma ferramenta CLI de backup incremental de e-mails, ainda em pleno desenvolvimento, voltada a provedores de e-mail que usam JMAP
      Eu queria permitir que os usuários pesquisassem seus backups e, como estou usando Rust, o Tantivy pareceu perfeito. A indexação de um único e-mail é tão rápida que nem precisei mover isso para uma thread separada, e a busca em milhares de e-mails também parece não ser problema
      Se você precisa de busca em uma aplicação Rust, vale a pena olhar o Tantivy
    • Pequeno relatório de bug: em https://progscrape.com/?search=grep aparece Error: PersistError(UnexpectedError("Storage fetch panicked"))
    • Há alguns dias usei o meilisearch para uma prova de conceito rápida; este repositório me fez querer dar outra olhada no Tantivy
      Basicamente, o que preciso é só busca full-text
  • Descobri o Tantivy recentemente dentro do ParadeDB. O ParadeDB é uma extensão do Postgres que tenta substituir o Elastic
    https://github.com/paradedb/paradedb/blob/dev/pg_search/Carg...
    Fiquei sabendo ao ouvir “Extending Postgres for High Performance Analytics (with Philippe Noël)”
    https://www.youtube.com/watch?v=NbOAEJrsbaM
    E ele também está no Quickwit, o projeto principal. É um projeto que lida com logs, traces e, em breve, métricas
    https://github.com/quickwit-oss/quickwit
    Usei Quickwit junto com ClickHouse em um projeto pessoal de busca multilíngue e ficou surpreendentemente bom. Finalmente apareceu uma combinação viável para chinês, japonês e coreano
    https://quickwit.io/docs/guides/add-full-text-search-to-your...
    O to_tsvector do PostgreSQL nunca funcionou muito bem para o meu caso de uso
    SELECT * FROM dump WHERE to_tsvector('english'::regconfig, hh_fullname) @@ to_tsquery('english'::regconfig, 'query');
    Espero que dê certo. Acho que vou automaticamente dar upvote em qualquer post que tenha Tantivy como palavra-chave

    • A combinação de indexação baseada em URL/REST e consultas de busca tratadas inteiramente dentro de SQL é um padrão de design interessante. Dá para fazer o mesmo com Postgres FDW
  • Recentemente colocamos em produção o Quickwit, que é baseado no Tantivy e feito pela mesma equipe, e indexamos dezenas de bilhões de objetos; estamos muito satisfeitos. A velocidade de indexação é excelente e a latência das consultas também é competitiva
    O mais importante é que a separação entre computação e armazenamento trouxe um valor enorme. Conseguimos subir um novo serviço de busca em cima de dezenas de bilhões de objetos no object storage, e até fazer agregações complexas, sem pagar por servidores de alta performance rodando por longos períodos, o que viabilizou novos casos de uso que, de outra forma, seriam bem caros
    Quando o caso de uso passa a justificar servidores de alta performance, o Quickwit também oferece a opção de armazenar dados em cache em cada servidor para melhorar o desempenho
    Como grande bônus, a equipe no Discord ajuda de forma muito rápida e gentil

  • Outro recurso é o índice de busca por trigramas em Go usado pelo etsy/hound[0]. Ele se baseia no artigo e no código de Russ Cox, “Regular Expression Matching with a Trigram Index”[1]
    [0] https://github.com/hound-search/hound
    [1] http://swtch.com/~rsc/regexp/regexp4.html
    Dependendo da necessidade, as alternativas ao Lucene também variam por caso de uso

  • Um ponto de atenção é que ainda não dá para adicionar/remover campos: https://github.com/quickwit-oss/tantivy/issues/470
    A única forma de adicionar campos é reindexar todos os dados em outro índice de busca

  • Encontrei o Tantivy enquanto procurava uma alternativa ao Meilisearch, que envia dados de telemetria por padrão. Ele parece mais um construtor de mecanismo de busca do que um mecanismo de busca em si, mas a configuração parece bem simples [0]
    [0]: https://github.com/quickwit-oss/tantivy-cli

    • O QuickWit também envia telemetria por padrão: https://quickwit.io/docs/telemetry
    • Tenho interesse, mas gostaria de usá-lo como biblioteca Rust e lidar apenas com tipos Rust, em vez de configuração JSON
      O SDK Java do Meilisearch também era bom. Não exigia CLI nem configuração manual; bastava apontar para as entidades do banco de dados para indexar a tabela inteira
      Seria ótimo se houvesse algo assim no Tantivy
    • Dá para desativar facilmente adicionando um único argumento de linha de comando, então rejeitá-lo por esse motivo, apesar de ele oferecer uma busca interativa utilizável, parece uma objeção pequena
  • O Tantivy também é usado para fornecer busca de texto completo em um produto interessante de banco de dados vetorial chamado LanceDb: https://lancedb.github.io/lancedb/fts/
    Da última vez que vi, isso só era possível por meio dos bindings Python, mas, pelo que sei, eles pretendem implementar bindings Rust nativos para dar suporte a outras plataformas

  • Alguns anos atrás, comecei um projeto pessoal porque o Elasticsearch era um monstro devorador de recursos e isso era absurdamente frustrante. Mesmo meu computador pessoal tinha mais recursos do que várias startups bem financiadas alocam para seus produtos, e ainda assim era assim
    Escolhi o Tantivy por dois motivos. Um era que eu queria construir tudo em Rust, e o outro era o próprio Tantivy. O desempenho é 10/10, a documentação é de altíssimo nível e a experiência de usar a biblioteca também é muito boa
    Infelizmente, o escopo do projeto era grande demais para eu dar conta sozinho no tempo livre, então acabei desistindo, mas o Tantivy continua sendo realmente excelente

  • Eu vinha acompanhando o Tantivy havia algum tempo. A persistência dos fundadores e o desempenho que o Tantivy alcançou recentemente são impressionantes
    Um grande aplauso para toda a equipe. Acredito firmemente que eles vão atingir seus objetivos

  • Como alguém que usou bastante Lucene e Solr, o que eu mais gostaria de ver é suporte a upgrade. Em geral, índices do Lucene, Solr e ES não podem ser atualizados para uma nova versão. Em alguns casos até dá, mas vou deixar isso de fora por conveniência
    Em projetos grandes, reindexar é uma operação muito cara e, às vezes, quase impossível
    Há casos em que é muito provável que seja absolutamente impossível. Por exemplo, quando o algoritmo de indexação de um tipo de dado muda em um campo de índice com perdas. Mas, em muitos casos, todas as informações continuam lá, então seria realmente ótimo poder identificar esses índices e fazer o upgrade