Compartilhar via


Implementando um separador de Word e lematizador

A Microsoft fornece separadores de palavras e lematizadores para vários idiomas. Este tópico descreve como implementar e usar separadores de palavras e lematizadores personalizados para idiomas e localidades além daqueles fornecidos pela Microsoft.

Observação

Separadores de palavras personalizados não tinham suporte temporário. Em julho de 2018, foi feita uma alteração no Windows Server 2019 que impedia que as DLLs sem uma assinatura da Microsoft fossem carregadas por SearchIndexer.exe. Essa limitação foi levantada em janeiro de 2021.

Este tópico é organizado da seguinte maneira:

Registrando uma DLL de recurso de linguagem

Cada DLL de recurso de linguagem deve implementar e exportar os pontos de entrada a seguir. A DLL pode ser registrada para estar em qualquer pasta.

  • DllMain é o ponto de entrada padrão para DLL.
  • DllRegisterServer registra a DLL no registro, como regsvr32.exe %SystemRoot%\MyFolder\wordbreaker.dll
  • DllCanUnloadNow permite que os clientes chamem esse ponto de entrada por meio do COM (Component Object Model) para determinar se é possível descarregar a DLL do recurso de linguagem.
  • DllUnRegisterServer remove a DLL do registro.

Registrando um idioma

O registro contém entradas específicas de idioma para o idioma que está sendo indexado e essas entradas controlam as partes dos processos de indexação e consulta que são específicos da linguagem. Essas entradas do Registro podem ser encontradas na chave do Registro a seguir.

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         ContentIndex
            Control
               Language
                  

Implementando um Word Beaker

Word disjuntores implementam IWordBreaker. O método IWordBreaker::BreakText executa todo o processamento e análise de texto. Para implementar um componente de separador de palavras, você deve ter heurística de linguagem para seu idioma. Isso inclui informações sobre sintaxe e morfologia. Talvez você também precise de uma lista de palavras para excluir ou incluir. Você cria o arquivo de palavras de ruído para sua localidade de idioma na lista de palavras excluídas. Para obter mais informações sobre considerações linguísticas e como essas considerações afetam as implementações de separador de palavras, consulte Considerações linguísticas e Unicode.

A finalidade main de IWordBreaker::BreakText é processar o texto continuamente do TEXT_SOURCE até que todo o texto seja processado ou até que o separador de palavras encontre um erro. Enquanto estiver nesse loop de processamento de dados, IWordBreaker::BreakText chama métodos de análise e utilitários que executam tarefas específicas para esse processo. Por exemplo, o separador de palavras alemão pode manipular palavras compostas, enquanto o separador de palavras francês pode processar diacríticos ou clitics. As funções específicas que o separador de palavras executa e a estratégia que ele usa na execução dessas tarefas dependem inteiramente dos requisitos para esse idioma.

Ao quebrar texto, os separadores de palavras identificam formulários "alternativos" para palavras que podem ter várias representações. Nenhuma relação semântica está implícita entre as palavras geradas. Na verdade, a palavra original pode não ser incluída entre a lista de alternativas. Os formulários alternativos são salvos na mesma posição no índice que a palavra original para indicar que são idênticos.

Quando um documento é incluído no índice, cada palavra recebe um valor inteiro que representa o deslocamento ou a distância da palavra desde o início de um documento. A distância relativa entre as palavras em uma consulta é comparada com os deslocamentos armazenados no índice de texto completo. A consulta "Where is Kyle's document" corresponde a qualquer documento com "Where" at offset n, "is" at n+1, "Kyle's" at n+2 e "document" at n+3. "Onde o documento de Kyle está arquivado na base de dados?" é representado como:

               
Where está Kyle Kyle's
documento Arquivado in o base de dados do banco de dados

 

Neste exemplo, o separador de palavras armazena formas alternativas para "Kyle" ("Kyle") e "database" ("base de dados") no índice. O separador de palavras gera e armazena palavras alternativas durante o processo de criação de índice nas seguintes condições:

  • Se for provável que uma palavra alternativa apareça como uma única palavra em uma consulta
  • Se não for provável que um lematizador derive a palavra original da alternativa

Gerar formulários de palavras alternativas aumenta o número de maneiras pelas quais as consultas representam e correspondem a uma frase, conforme mostrado nas seguintes variações:

  1. Onde o documento de Kyle está arquivado no banco de dados
  2. Onde está o documento de Kyle arquivado no banco de dados
  3. Onde o documento de Kyle está arquivado na base de dados
  4. Onde está o documento de Kyle arquivado na base de dados

WordSink e PhraseSink

Word disjuntores usam os objetos IWordSink e IPhraseSink para coletar e armazenar todas as palavras e frases que extraem do texto. Um separador de palavras armazena palavras em um formulário o mais próximo possível do formulário de palavra original no documento. IPhraseSink armazena frases no momento da consulta. As frases melhoram a relevância dos resultados da consulta porque sequências mais longas de palavras são mais raras e fornecem maior distinção do que frases menores. Quando o indexador coloca uma frase no IPhraseSink no momento da consulta, ele cria uma instância do separador de palavras para dividir a frase em palavras. Em seguida, o indexador avalia a frase verificando se as palavras na frase ocorrem adjacentes umas às outras no índice. Por exemplo, se "ABCD" ocorrer no índice nas posições x, x+1, x+2 e x+3, a correspondência de frase ocorrerá se qualquer subcadeia de caracteres adjacente de "ABCD" for enviada em uma consulta. Essa estratégia é eficaz para separadores de palavras baseados em caracteres que dividem frases e palavras longas durante a criação do índice e que geram frases durante o tempo de consulta.

Quebras

Quebras são os espaços entre palavras. Espaço em branco, pontuação, formatação ou apenas a natureza da linguagem em si pode causar quebras. Há quatro tipos diferentes de quebras que o indexador usa: fim da palavra (EOW), fim da frase (EOS), fim do parágrafo (EOP) e fim do capítulo (EOC). A quebra de EOW é a quebra padrão. Após cada token, cada quebra indica uma distância semântica diferente entre as palavras em ambos os lados. As palavras separadas pelo EOW têm o link semântico mais apertado, seguido por EOS, EOP e EOC. Várias chamadas para IWordSink::P utBreak são cumulativas e são análogas à inserção de palavras ou frases nulas.

Escalabilidade, desempenho e segurança

A maneira como o separador de palavras responde a chamadas simultâneas é determinada em grande parte pela sua escolha de modelo de threading. O indexador é um aplicativo de thread único. Para que os separadores de palavras funcionem em um ambiente de thread único, os separadores de palavras devem ser gravados usando um modelo de threading "gratuito" ou "ambos". Word separadores não devem se registrar com COM usando o modelo de threading "apartment".

Recomendamos que os separadores de palavras evitem estados globais e armazenem dados na instância do separador de palavras. O único conteúdo que deve ser armazenado na implementação do separador de palavras é para os parâmetros fQuery e ulMaxTokenSize. Word separadores não devem ser mais do que duas vezes mais lentos do que o parâmetro de comparação estabelecido pelo separador de palavras em inglês. Word desempenho do disjuntor também deve melhorar com maior capacidade de hardware.

Word separadores para a execução do indexador no contexto de segurança do Sistema Local. Eles devem ser gravados para gerenciar buffers e para serem empilhados corretamente. Todas as cópias de cadeia de caracteres devem ter verificações explícitas para proteger contra estouros de buffer. Você sempre deve verificar o tamanho alocado do buffer e testar o tamanho dos dados em relação ao tamanho do buffer. Word separadores não podem assumir que o texto passado para o método IWordBreaker::BreakText está bem formado. Para obter mais informações sobre como solucionar problemas de separadores de palavras, consulte Solução de problemas de recursos de linguagem e práticas recomendadas.

Implementando um lematizador

Lematizadores implementam a interface IStemmer . O método IStemmer::GenerateWordForms gera uma lista de formulários de palavras inflexionados para uma palavra de entrada específica. Para implementar um componente lematizador, você deve ter heurística de linguagem para sua linguagem. Isso inclui informações sobre morfologia. Talvez você também precise de uma lista de palavras para excluir ou incluir. Para obter mais informações sobre considerações linguísticas e como essas considerações afetam as implementações de lematizador, consulte Considerações linguísticas e Unicode.

Recomendamos que os lematizadores não gerem o caso congênito ou possessivo para palavras. Por exemplo, "David" não é gerado como uma forma alternativa para "David". O separador de palavras gera "David" e "David" quando analisa "David".

O lematizador usa o objeto IWordFormSink para coletar a lista de palavras alternativas. IWordFormSink::P utWord gera a palavra final do lematizador. Em todos os casos, essa palavra final é a mesma que a palavra de entrada de IStemmer::GenerateWordForms. Por exemplo, dada a palavra "nadar", o lematizador gera as seguintes formas de palavra: "natação", "nadador", "nada", "nadou" e "swum", através de chamadas para IWordFormSink::P utAltWord. O lematizador gera "natação" por meio de IWordFormSink::P utWord.

Escalabilidade, desempenho e segurança

Lematizadores, como separadores de palavras, devem usar um modelo de threading "gratuito" e registrar com COM com seu modelo de threading definido como "gratuito" ou "ambos". O Windows Search chama instâncias separadas do lematizador de threads diferentes ao mesmo tempo. Portanto, os lematizadores devem ter dados mínimos de instância.

A precisão do lematizador tem um impacto significativo na relevância da consulta. Se o lematizador conter o texto incorretamente, as consultas poderão retornar resultados imprevisíveis e imprecisos. Os lematizadores devem lidar com centenas de consultas por segundo sem afetar negativamente o desempenho da consulta. O desempenho do lematizador deve melhorar com maior capacidade de hardware. Para obter informações sobre como solucionar problemas de lematizadores, consulte Solução de problemas de recursos de linguagem e práticas recomendadas.

Os lematizadores do Windows Search são executados no contexto de Segurança Local. Eles devem ser gravados para gerenciar buffers e para serem empilhados corretamente. Todas as cópias de cadeia de caracteres devem ter verificações explícitas para proteger contra estouros de buffer. Você sempre deve verificar o tamanho alocado do buffer e testar o tamanho dos dados em relação ao tamanho do buffer.

Estendendo recursos de linguagem

Noções básicas sobre componentes de recursos de linguagem

Considerações linguísticas e Unicode

Solução de problemas de recursos de linguagem e práticas recomendadas