Altere o tipo de campo usado pelo Solr para indexar seus dados

As pessoas que acompanharam meus últimos tweets e me conhecem na vida real sabem que estou aprendendo Solr e, principalmente, como ele funciona com o Drupal.

O problema que tive é que quando você usa o Solr, ele tem muitas vantagens.
Uma das desvantagens é que você não pode pesquisar substring de palavras.
Por exemplo, digamos que você tenha um título de nó chamado: ” Como aprender Drupal em poucas palavras “, você não será capaz de pesquisar a string nut ou rupa . O que às vezes acaba sendo útil, especialmente para títulos de nós.

Por que isso não é possível?

O Solr está indexando o título do seu nó usando o tipo de texto , se você olhar no esquema para a definição do tipo de campo ‘texto’ , você notará que o filtro solr.EdgeNGramFilterFactory não está habilitado e, portanto, a pesquisa de n-gram está não é possível usar esse tipo.

Na verdade, isso é possível, mas você precisa editar seu arquivo schema.xml manualmente e adicionar alguns filtros nele. Mas esta não é uma boa prática. Veremos aqui que há uma nova maneira de fazer isso sem alterar os arquivos principais.

O que é um N-grama?

Nos campos da linguística computacional e probabilidade, um n-grama é uma sequência contígua de n itens de uma dada sequência de texto ou fala. Os itens podem ser fonemas, sílabas, letras, palavras ou pares de bases de acordo com a aplicação. Os n-gramas normalmente são coletados de um corpus de texto ou fala. (fonte: Wikipedia )

Exemplo com a palavra francesa ‘ praline ‘:

  • 1 grama: p, r, a, l, i, n, e
  • 2 gramas: pr, ra, al, li, in, ne
  • 3 gramas: pra, ral, ali, lin, ine
  • 4 gramas: pral, rali, alin, linha
  • 5 gramas: prali, ralin, aline
  • 6 gramas: pralin, raline

Como habilitá-lo no Drupal

Por padrão, o módulo search_api_solr permite que você use uma lista de tipos de dados predefinidos:

  • Texto completo
  • Corda
  • Inteiro
  • Decimal
  • Encontro
  • Duração
  • boleano
  • URI

Esses tipos de dados são mapeados para seus campos e é assim que o Solr os indexa.

Com o hook_search_api_data_type_info , você pode definir seu próprio tipo de dados.
Então, com algumas linhas extras em seu módulo, como este:

function mymodule_search_api_data_type_info() {
return array(
'edge_n2_kw_text' => array(
'name' => t('Fulltext (w/ partial matching)'),
'fallback' => 'text',
'prefix' => 'tem',
'always multiValued' => TRUE,
),
);
}

O prefixo usado por este tipo de dado é tem , você pode verificar sua definição no arquivo schema.xml:

<dynamicField name="tem_*" type="edge_n2_kw_text" indexed="true" stored="true" multiValued="true" omitTermFreqAndPositions="true" />

Como você pode ver, os campos com prefixo tem_ usam o tipo edge_n2_kw_text , que também é definido no arquivo shema.xml.

Você pode adicionar seu próprio tipo de dados na lista de seleção de tipo de dados ao mapeá-los para seus campos.
A chave da matriz retornada geralmente é um tipo de campo definido no schema.xml.

Usando este gancho, você será capaz de mapear qualquer campo para o tipo de dados edge_n2_kw_text , este tipo de dados é definido em schema.xml:

<fieldType name="edge_n2_kw_text" class="solr.TextField" omitNorms="true" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

Como você pode ver, o filtro solr.EdgeNGramFilterFactory está habilitado neste tipo de campo e isso significa que será habilitado no campo para o qual será mapeado. É Magica !

Sugiro que você leia o número 1846860 , foi aqui que comecei a fazer algumas perguntas sobre isso e também encontrei a solução.

Aqui está a documentação sobre os parâmetros do filtro e não se esqueça que você também pode criar seus próprios tipos no arquivo schema_extra_types.xml .

Atenção

Esteja ciente de que você não deve usar isso em um campo de texto grande, pode quebrar seu índice, um bom exemplo de uso é usá-lo apenas nos títulos dos campos.

Para campos grandes, o melhor é usar curingas, e sugiro ler esta edição # 1879762 para entender como implementá-lo.

Espero que este tutorial ajude as pessoas!