Abril de 2019

Volume 34 – Número 4

[.NET]

Como implementar seu próprio Enterprise Search

Por Xavier Morera

Você provavelmente pensa que a função de pesquisa é algo muito trivial. Você a usa diariamente para realizar diversos tipos de tarefas, desde achar um quarto para a sua próxima viagem até encontrar as informações necessárias para o seu trabalho. Uma pesquisa implementada adequadamente pode ajudar você a economizar dinheiro — ou ganhar dinheiro. E mesmo em um ótimo aplicativo, uma pesquisa ruim ainda cria uma experiência insatisfatória do usuário.

O problema é que apesar da sua importância, a pesquisa é uma das funcionalidades mais mal compreendidas na TI, e é percebida somente quando não existe ou quando não funciona. Mas a pesquisa não precisa ser um recurso obscuro que é difícil de implementar. Neste artigo, vou explicar como você pode desenvolver uma API de pesquisa empresarial em C#.

Para saber mais sobre pesquisa, você precisa de um mecanismo de pesquisa. Há muitas opções, de software livre a comercial e outras, muitas dos quais aproveitam a Lucene internamente, a biblioteca de recuperação de informações recomendada. Isso inclui o Azure Search, ElasticSearch e Solr. Hoje, vou usar o Solr. Por que? Ele já existe há muito tempo, possui uma boa documentação, uma comunidade vibrante, muitos usuários notáveis e eu mesmo o usei para implementar a pesquisa em muitos aplicativos, de sites pequenos a grandes corporações.

Obter o Solr

A instalação de um mecanismo de pesquisa pode parecer uma tarefa complicada e, na verdade, se você estiver configurando uma instância de Solr de produção que precise para dar suporte a um grande número de consultas por segundo (QPS), então, sim, ela pode ser complicada. (A taxa de QPS é uma métrica comum usada para se referir à carga de trabalho de pesquisa.)

Essas etapas são abordadas em detalhes na seção “Instalar o Solr” da documentação do Solr (lucene.apache.org/solr), e também na seção “A instância do Solr bem configurada” no “Guia de Referência do Apache Solr” (bit.ly/2IK7mqY). Mas eu só preciso de uma instância de desenvolvimento do Solr, portanto, posso simplesmente acessar bit.ly/2tEXqoo e obter uma versão binária; o solr-7.7.0.zip serve.

Eu baixo o arquivo .zip, descompacto-o, abro a linha de comando e altero o diretório para a raiz da pasta onde eu descompactei o arquivo. Em seguida emito seguinte comando:

> bin\solr.cmd start

É só isso. Basta navegar até http://localhost:8983, onde eu sou saudado com a interface do usuário do administrador do Solr, mostrada na Figura 1.

Um mecanismo de pesquisa em funcionamento
Figura 1 Um mecanismo de pesquisa em funcionamento

Obter dados

Em seguida, preciso de dados. Há muitos conjuntos de dados disponíveis com dados interessantes, mas todos os dias milhares de desenvolvedores acabam acessando o StackOverflow porque eles não lembram exatamente como gravar em um arquivo; não conseguem sair do VIM; ou precisam de um trecho de código em C# que resolva um problema específico. A boa notícia é que os dados de StackOverflow estão disponíveis como um despejo em XML que contém aproximadamente 10 milhões de perguntas e respostas, tags, notificações, informações de usuário anônimo e muito mais (bit.ly/1GsHll6).

Melhor ainda, posso selecionar um conjunto de dados com o mesmo formato de um site do StackExchange menor que contém apenas alguns milhares de perguntas. Posso testar com o menor conjunto de dados primeiro e, posteriormente, fortalecer a infraestrutura para trabalhar com mais dados.

Vou começar com os dados do datascience.stackexchange.com, que contém cerca de 25 mil postagens. O arquivo é chamado datascience.stackexchange.com.7z. Eu o baixo e extraio o Posts.xml.

Alguns conceitos necessários

Eu tenho um mecanismo de pesquisa e os dados, portanto, é um bom momento para rever alguns conceitos importantes. Se você está acostumado a trabalhar com bancos de dados relacionais, provavelmente algumas coisas serão familiares.

O índice é onde um mecanismo de pesquisa armazena todos os dados que são coletados para a pesquisa. Em um alto nível, o Solr armazena os dados no que chamamos de um índice invertido. Em um índice invertido, palavras (ou tokens) apontam para documentos específicos. Quando procura uma palavra específica, você está fazendo uma consulta. Se a palavra for encontrada (uma ocorrência ou uma correspondência), o índice indicará quais documentos contêm essa palavra e sua localização.

O esquema é como você especifica a estrutura dos dados. Cada registro é chamado de um documento e, da mesma forma que você definiria as colunas de um banco de dados, você especifica os campos de um documento em um mecanismo de pesquisa.

Você cria o esquema com a edição de um arquivo XML chamado schema.xml, definindo os campos com seus respectivos tipos. No entanto, você também pode usar campos dinâmicos, em que um novo campo é criado automaticamente quando um campo desconhecido é adicionado. Isso pode ser útil quando você não estiver totalmente seguro de todos os campos que estão presentes nos dados.

Você já deve ter notado que o Solr é bastante semelhante a um armazenamento de documentos do NoSQL, já que ele pode conter documentos com campos que são desnormalizados e não necessariamente consistentes para toda a coleção de documentos.

O modo sem esquema é outra maneira de modelagem de dados dentro do índice. Nesse caso, você não informa explicitamente ao Solr quais campos serão indexados. Você simplesmente adiciona os dados e o Solr cria um esquema baseado no tipo de dados que está sendo adicionado ao índice. Para usar o modo sem esquema, você deve ter um esquema gerenciado, o que significa que você não pode editar manualmente os campos. Isso é especialmente útil para uma fase de exploração de dados ou de prova de conceito.

Vou usar um esquema editado manualmente, que é a abordagem recomendada para produção, já que ela gera maior controle.

A indexação é o processo de adicionar dados ao índice. Durante a indexação, um aplicativo lê de fontes diferentes e prepara os dados para ingestão. Essa é a palavra usada para adicionar documentos; talvez você também ouça o termo alimentação.

Depois que os documentos são indexados, é possível fazer a pesquisa, e espera-se que sejam retornados os documentos mais relevantes para uma determinada pesquisa nas primeiras posições. 

A classificação de relevância é como os resultados mais apropriados são retornados primeiro. Esse é um conceito fácil de explicar. No melhor dos casos, você executa uma consulta e o mecanismo de pesquisa “lê” sua mente, retornando exatamente os documentos que você estava procurando.

Precisão vs. revocação: Precisão se refere ao número de resultados relevantes (a qualidade dos resultados), enquanto a revocação é a quantidade de resultados relevantes em relação ao total de resultados retornados (a quantidade ou totalidade dos resultados). 

Analisadores, tokenizers e filtros: Quando dados são indexados ou pesquisados, um analisador examina o texto e gera um fluxo de token. As transformações são aplicadas por meio de filtros para tentar corresponder as consultas aos dados indexados. Você precisa entender esses conceitos se o seu objetivo é ter uma compreensão mais profunda da tecnologia do mecanismo de pesquisa. Felizmente, você pode começar a criar um aplicativo com apenas uma visão geral de alto nível.

Compreendendo os dados

Eu preciso compreender os dados para poder modelar o índice. Para isso, abro o Posts.xml e o analiso. 

Os dados têm essa aparência. O nó de postagens contém muitos nós filho de linha. Cada nó filho corresponde a um registro, com cada campo exportado como um atributo em cada nó filho. Os dados que serão ingeridos no mecanismo de pesquisa são bem limpos, o que é bom:

<posts>
  <row Id=”5” PostTypeId=”1” CreationDate=”2014-05-13T23:58:30.457”
    Score=”9” ViewCount=”448” Body=”<Contains the body of the question or answer>”
      OwnerUserId=”5” LastActivityDate=”2014-05-14T00:36:31.077”
        Title=”How can I do simple machine learning without hard-coding behavior?”
          Tags=”<machine-learning,artificial-intelligence>;” AnswerCount=”4”
            CommentCount=”5” FavoriteCount=”1”
              ClosedDate=”2014-05-14T14:40:25.950” />
  ...
</posts>

De relance, eu posso ver rapidamente como há campos de diferentes tipos. Há um identificador exclusivo, algumas datas, alguns campos numéricos, alguns campos de texto curtos e longos e alguns campos de metadados. Para economizar tempo, eu removi o Corpo, que é um campo de texto grande, mas todos os outros estão em seu estado original.

Configurar o Solr para usar um esquema clássico

Há várias maneiras de especificar a estrutura dos dados para o índice. Por padrão, o Solr usa um esquema gerenciado, o que significa que ele usa o modo sem esquema. Mas eu quero criar o esquema manualmente — o que chamamos de um esquema clássico — portanto, preciso fazer algumas alterações na configuração. Primeiro, vou criar uma pasta para armazenar minha configuração de índice, que chamarei de msdnarticledemo. A pasta está localizada em <solr>\server\solr\, em que <solr> é a pasta onde eu descompactei o Solr.

Em seguida, crio um arquivo de texto na raiz dessa pasta chamado core.properties, que precisa apenas da seguinte linha: name=msdnarticledemo. Esse arquivo é usado para criar um núcleo do Solr, que é apenas uma instância em execução de um índice da biblioteca Lucene. Talvez você também ouça a palavra coleção, que pode ter um significado diferente dependendo do contexto. Para a minha intenção e finalidades aqui, um núcleo é o equivalente a um índice.

Agora preciso copiar o conteúdo de um índice de exemplo limpo para usar como base. O Solr inclui um índice desse tipo em <solr>\server\solr\configsets\_default. Eu copio a pasta conf para msdnarticledemo.

Na próxima etapa, que é muito importante, posso dizer ao Solr que desejo usar um esquema clássico; ou seja, que vou editar manualmente meu esquema. Para fazer isso, abro o arquivo solrconfig.xml e adiciono a seguinte linha:

<schemaFactory class=”ClassicIndexSchemaFactory”/>

Além disso, ainda dentro desse arquivo, comento dois nós, o updateRequestProcessorChain com:

name=”add-unknown-fields-to-the-schema”
and updateProcessor with:
name=”add-schema-fields”

Esses dois recursos que permitem ao Solr adicionar novos campos durante a indexação de dados no modo sem esquema. Eu também removo o comentário dentro deste nó xml, considerando que "--" não é permitido dentro de comentários xml.

Por fim, renomeio o esquema gerenciado para schema.xml. Desse modo, o Solr está pronto para usar um esquema criado manualmente.

Como criar o esquema

A próxima etapa é definir os campos no esquema, dessa forma, abro o arquivo schema.xml e rolo para baixo até localizar a definição de id, _text_ e _root_.

Isso é como cada campo é definido, como um nó <field> xml que contém:

  • name: o nome de cada campo.
  • type: o tipo do campo; você pode modificar como cada tipo é tratado no schema.xml.
  • indexed: true indica que este campo pode ser usado para pesquisa.
  • stored: true indica que este campo pode ser usado para exibição.
  • required: true indica que este campo deve ser indexado, caso contrário ocorrerá um erro.
  • multiValued: true indica que este campo pode conter mais de um valor.

Isso pode ser confuso a princípio, mas alguns campos podem ser exibidos, mas não pesquisados e alguns podem ser pesquisados, mas poderão não ser recuperados após a indexação. Há outros atributos avançados, mas não quero entrar em detalhes sobre eles agora.

A Figura 2 mostra como eu defino os campos no esquema de postagens. Para tipos de texto, eu tenho vários, incluindo string, text_get_sort e text_general. Pesquisa de texto é um dos principais objetivos da pesquisa e, por este motivo, há diferentes tipos compatíveis com texto. Também tenho os tipos date, integer, float e um campo que contém mais de um valor, Tags.

Figura 2 Campos no Schema.xml

<field name=”id” type=”string” indexed=”true” stored=”true”
  required=”true” multiValued=”false” />
<field name=”postTypeId” type=”pint” indexed=”true” stored=”true” />
<field name=”title” type=”text_gen_sort” indexed=”true”
  stored=”true” multiValued=”false”/
<field name=”body” type=”text_general” indexed=”false”
  stored=”true” multiValued=”false”/>
<field name=”tags” type=”string” indexed=”true” stored=”true”
  multiValued=”true”/>
<field name=”postScore” type=”pfloat” indexed=”true” stored=”true”/>
<field name=”ownerUserId” type=”pint” indexed=”true” stored=”true” />
<field name=”answerCount” type=”pint” indexed=”true” stored=”true” />
<field name=”commentCount” type=”pint” indexed=”true” stored=”true” />
<field name=”favoriteCount” type=”pint” indexed=”true” stored=”true” />
<field name=”viewCount” type=”pint” indexed=”true” stored=”true” />                
<field name=”creationDate” type=”pdate” indexed=”true” stored=”true” />
<field name=”lastActivityDate” type=”pdate” indexed=”true” stored=”true” />
<field name=”closedDate” type=”pdate” indexed=”true” stored=”true” />

O que vem em seguida pode variar dependendo da implementação. No momento, eu tenho muitos campos e posso especificar qual deles quero pesquisar e a importância desse campo em relação aos outros campos.

Mas, para começar, posso usar o campo de catch-all _text_ para realizar uma pesquisa em todos os meus campos. Basta criar um copyField e informar ao Solr que os dados de todos os campos devem ser copiados para o meu campo padrão:

<copyField source=”*” dest=”_text_”/>

Agora, quando executo uma pesquisa, o Solr pesquisa dentro deste campo e retorna qualquer documento que corresponda à minha consulta.

Em seguida, reinicio o Solr para carregar o núcleo e aplicar as alterações, executando este comando:

> bin\solr.cmd restart

Agora estou pronto para começar a criar um aplicativo em C#.                 

Como obter o SolrNet e modelagem de dados

O Solr oferece uma API semelhante a uma API REST que você pode usar facilmente a partir de qualquer aplicativo. Melhor ainda, há uma biblioteca chamada SolrNet (bit.ly/2XwkROA) que fornece uma abstração sobre Solr, permitindo que você trabalhe facilmente com objetos fortemente tipados, com muitas funcionalidades para tornar o desenvolvimento do aplicativo de pesquisa mais rápido.

A maneira mais fácil de obter o SolrNet é instalar o pacote SolrNet do NuGet. Vou incluir a biblioteca no novo aplicativo de console que criei usando o Visual Studio 2017. Você talvez queira baixar também os pacotes adicionais, como SolrCloud, que são necessários para usar outros mecanismos de controle de inversão e para ter acesso a outras funcionalidades.

Agora preciso modelar os dados no meu índice dentro do meu aplicativo de console. Isso é bem simples: Posso simplesmente criar um novo arquivo de classe chamado Post.cs, conforme mostrado na Figura 3.

Figura 3 Modelo de documento de postagem

class Post
{
  [SolrUniqueKey(“id”)]
  public string Id { get; set; }
  [SolrField(“postTypeId”)]
  public int PostTypeId { get; set; }
  [SolrField(“title”)]
  public string Title { get; set; }
  [SolrField(“body”)]
  public string Body { get; set; }
  [SolrField(“tags”)]
  public ICollection<string> Tags { get; set; } = new List<string>();
  [SolrField(“postScore”)]
  public float PostScore { get; set; }
  [SolrField(“ownerUserId”)]
  public int? OwnerUserId { get; set; }
  [SolrField(“answerCount”)]
  public int? AnswerCount { get; set; }
  [SolrField(“commentCount”)]
  public int CommentCount { get; set; }
  [SolrField(“favoriteCount”)]
  public int? FavoriteCount { get; set; }
  [SolrField(“viewCount”)]
  public int? ViewCount { get; set; }
  [SolrField(“creationDate”)]
  public DateTime CreationDate { get; set; }
  [SolrField(“lastActivityDate”)]
  public DateTime LastActivityDate { get; set; }
  [SolrField(“closedDate”)]
  public DateTime? ClosedDate { get; set; }
}

Isso não é nada mais do que um objeto CLR básico (POCO) que representa cada documento individual no meu índice, mas com um atributo que informa ao SolrNet para qual campo cada propriedade é mapeada.

Criar um aplicativo de pesquisa

Quando você cria um aplicativo de pesquisa, você normalmente cria duas funcionalidades separadas:

O indexador: este é o aplicativo que preciso criar primeiro. Para ter dados a serem pesquisados, eu preciso fornecer esses dados ao Solr. Isso pode envolver a leitura de dados de várias fontes, convertê-los de vários formatos e muito mais, até que ele esteja finalmente pronto para a pesquisa.

O aplicativo de pesquisa: Quando eu tiver dados no meu índice, posso começar a trabalhar no aplicativo de pesquisa.

Nos dois, a primeira etapa exige a inicialização do SolrNet, que pode ser feita com a seguinte linha no aplicativo de console (certifique-se de que o Solr esteja em execução!):

Startup.Init<Post>(“http://localhost:8983/solr/msdnarticledemo”);

Vou criar uma classe para cada funcionalidade no meu aplicativo.

Como criar o indexador

Para indexar os documentos, eu começo obtendo a instância de serviço SolrNet, que me permite iniciar todas as operações com suporte:

var solr = ServiceLocator.Current.GetInstance<ISolrOperations<Post>>();

Em seguida, preciso ler o conteúdo de Posts.xml em um XMLDocument, que envolve a iteração em cada nó, criando um novo objeto de postagem, extraindo cada atributo de XMLNode e atribuindo-os à propriedade correspondente.

Observe que os dados são armazenados desnormalizados no campo de recuperação de informações ou de pesquisa. Por outro lado, quando você está trabalhando com bancos de dados, você geralmente normaliza os dados para evitar a duplicação. Em vez de adicionar o nome do proprietário a uma postagem, você adiciona uma Id de inteiro e cria uma tabela separada para corresponder a Id a um Nome. Na pesquisa, no entanto, você adiciona o nome como parte da postagem e, assim, os dados são duplicados. Por que? Porque quando os dados são normalizados, você precisa executar junções para recuperação, que são muito caras. Mas um dos principais objetivos de um mecanismo de pesquisa é a velocidade. Os usuários esperam pressionar um botão e obter os resultados que desejam imediatamente.

Agora, de volta à criação do objeto de postagem. Na Figura 4, vou mostrar apenas três campos, pois adicionar outros é bem fácil. Observe como as Tags tem diversos valores e que estou verificando a presença de valores nulos para evitar exceções.  

Figura 4 Preenchimento dos campos

Post post = new Post();
post.Id = node.Attributes[“Id”].Value;
if (node.Attributes[“Title”] != null)
{
  post.Title = node.Attributes[“Title”].Value;
}
if (node.Attributes[“Tags”] != null){
  post.Tags = node.Attributes[“Tags”].Value.Split(new char[] { ‘<’, ‘>’ })
    .Where(t => !string.IsNullOrEmpty(t)).ToList();}
// Add all other fields

Depois que eu tiver preenchido o objeto, posso adicionar cada instância usando o método Add:

solr.Add(post);

Como alternativa, posso criar uma coleção de postagens e adicionar postagens em lotes usando AddRange:

solr.AddRange(post_list);

Qualquer uma dessas abordagens funciona, mas foi observado em muitas implantações de produção que adicionar documentos em lotes de 100 unidades tende a ajudar no desempenho. Observe que a adição de um documento não o torna pesquisável. Eu preciso confirmar:

solr.Commit();

Agora, vamos executar e, dependendo da quantidade de dados que está sendo indexada e da máquina na qual eles estão em execução, isso pode levar de alguns segundos a alguns minutos.

Quando o processo for concluído, posso navegar na interface do usuário de administrador do Solr, procurar uma lista suspensa na parte central esquerda que diz Seletor de núcleo e escolher meu núcleo (msdnarticledemo). Na guia Visão geral posso ver as Estatísticas, que me dizem quantos documentos eu indexei.

O meu despejo de dados tinha 25.488 postagens que correspondem ao que eu vejo:

Statistics
  Last Modified: less than a minute ago
  Num Docs:25488
  Max Doc:25688

Agora que tenho dados no meu índice, posso começar a trabalhar no lado do aplicativo.

Como pesquisar no Solr

Antes de voltar para o Visual Studio, quero demonstrar uma pesquisa rápida na interface do usuário de administrador do Solr e explicar alguns dos parâmetros que estão disponíveis.

No núcleo msdnarticledemo, vou clicar em Consulta e pressionar o botão azul na parte inferior que diz Executar consulta. São retornados todos os meus documentos no formato JSON, conforme mostrado na Figura 5.

Uma consulta em Solr feita através da interface do usuário do administrador
Figura 5 Uma consulta em Solr feita através da interface do usuário do administrador

Assim, o que exatamente eu acabei de fazer e por que foram retornados todos os documentos no índice? A resposta é simples. Dê uma olhada nos parâmetros — a coluna com o manipulador de solicitação (qt) na parte superior. Como você pode ver, um parâmetro é chamado de q e ele tem um valor de *:*.  Isso é o que retornou todos os documentos. Na verdade, a consulta que eu executei era para pesquisar todos os campos para todos os valores, usando um par chave-valor. Se, em vez disso, eu quisesse apenas pesquisar por Solr no título, o valor de q seria Title:Solr. 

Isso é muito útil para a criação de consultas mais complicadas que fornecem diferentes pesos a cada campo, o que faz sentido. Uma palavra ou frase que é encontrada em um título é mais importante do que uma palavra ou frase encontrada no conteúdo. Por exemplo, se um documento tem Pesquisa empresarial no título, é muito provável que o documento inteiro seja sobre pesquisa empresarial. Mas se eu encontrar essa frase em qualquer parte do corpo de um documento, pode ser que ela seja apenas uma referência a algo vagamente relacionado ao que eu desejo.

O parâmetro q é provavelmente o mais importante, já que ele recupera documentos em ordem de relevância, calculando uma pontuação. Mas há uma série de outros parâmetros que você pode usar por meio do manipulador de solicitação para configurar como as solicitações são processadas pelo Solr, incluindo a consulta de filtro (fq), classificação, a lista de campos (fl) e muitos outros que podem ser encontrados na documentação do Solr em bit.ly/2GVmYGl. Com esses parâmetros você pode começar a criar consultas mais complicadas. É preciso paciência para dominar esse assunto, mas quanto mais você aprender, melhores serão as classificações de relevância que você obterá.

Tenha em mente que a interface do usuário do administrador não é como um aplicativo funciona com o Solr. Para essa finalidade, a interface REST é usada. Se você olhar logo acima dos resultados, há um link em uma caixa cinza que contém a chamada para essa consulta específica. Clicar nela abre uma nova janela, que contém a resposta.

Esta é minha consulta:

http://localhost:8983/solr/msdnarticledemo/select?q=*%3A*&wt=json

O SolrNet faz chamadas como esta nos bastidores, mas isso apresenta objetos que posso usar a partir do meu aplicativo .NET. Agora criarei um aplicativo de pesquisa básica.

Como criar o aplicativo de pesquisa

Nesse caso específico, vou pesquisar as perguntas no meu conjunto de dados, em todos os campos. Considerando que os dados contêm perguntas e respostas, posso filtrar por PostTypeId, com “1”, o que significa que essa é uma pergunta.  Para fazer isso, posso usar uma consulta de filtro, o parâmetro fq.

Além disso, eu vou definir algumas opções de consulta para retornar uma página de resultados de cada vez, ou seja, linhas, para indicar quantos resultados, e o StartOrCursor para especificar o deslocamento (inicial). E, claro, vou definir a consulta.

A Figura 6 mostra o código necessário para executar uma pesquisa básica, com a consulta sendo o texto que estou procurando.

Figura 6 Executando uma pesquisa básica

QueryOptions query_options = new QueryOptions
{
  Rows = 10,
  StartOrCursor = new StartOrCursor.Start(0),
  FilterQueries = new ISolrQuery[] {
    new SolrQueryByField(“postTypeId”, “1”),
    }
};
// Construct the query
SolrQuery query = new SolrQuery(keywords);
// Run a basic keyword search, filtering for questions only
var posts = solr.Query(query, query_options);

Depois de executar a consulta, obtenho postagens, que é um objeto SolrQueryResults. Ele contém uma coleção de resultados, bem como várias propriedades com vários objetos que fornecem outras funcionalidades. Agora que tenho esses resultados posso exibi-los para o usuário.

Como restringir os resultados

Em muitos casos, os resultados originais podem ser bons, mas o usuário talvez queira restringi-los a um campo de metadados específico. É possível fazer uma busca detalhada por um campo usando as facetas. Em uma faceta posso obter uma lista de pares chave-valor. Por exemplo, com Tags recebo cada marca e quantas vezes cada uma delas ocorre. Facetas são normalmente usadas com campos numéricos, de data ou de cadeia de caracteres. Campos de texto são complicados.

Para habilitar as facetas, eu preciso adicionar uma nova faceta, a QueryOption:  

Facet = new FacetParameters
{
  Queries = new[] {
    new SolrFacetFieldQuery(“tags”)
  }
}

Agora posso recuperar minhas facetas de posts.FacetFields[“tags”], que é uma coleção de pares chave-valor que contém cada marca específica, e quantas vezes cada marca ocorre no conjunto de resultados.

Em seguida, posso permitir que o usuário selecione quais marcas devem ser pesquisadas, reduzindo o número de resultados com uma consulta de filtro, retornando documentos relevantes, se tudo der certo. 

Melhorar a pesquisa — qual o próximo passo?

Até agora, eu abordei os conceitos fundamentais da implementação de uma pesquisa básica em C# com o Solr e SolrNet usando as perguntas de um dos sites do StackExchange. No entanto, isso é apenas o começo de um novo percurso no qual posso me aprofundar na arte de retornar resultados relevantes usando o Solr.

Algumas das etapas a seguir incluem pesquisar por campos individuais com pesos diferentes; realçar resultados para mostrar correspondências no conteúdo; usar sinônimos para retornar resultados que estão relacionados, mas que podem não conter as palavras exatas que foram pesquisadas; lematização, que é o que reduz as palavras ao seu radical para aumentar o recall; pesquisa fonética, que ajuda os usuários internacionais; e muito mais.

Enfim, aprender a implementar a pesquisa é uma habilidade valiosa que pode potencialmente gerar um retorno importante em seu futuro como um desenvolvedor.

Para acompanhar este artigo, eu criei um projeto de pesquisa básica, conforme mostrado na Figura 7, que você pode baixar para saber mais sobre a pesquisa empresarial. Boa pesquisa!

Um exemplo de projeto de pesquisa
Figura 7 Um exemplo de projeto de pesquisa


Xavier Moreraajuda os desenvolvedores a entender pesquisa empresarial e Big Data. Ele cria cursos na Pluralsight e, às vezes, na Cloudera. Ele trabalhou por muitos anos na Search Technologies (agora parte da Accenture), lidando com implementações de pesquisa. Ele mora na Costa Rica, e você pode encontrá-lo em xaviermorera.com.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Jose Arias (Accenture), Jonathan Gonzalez (Accenture)
Jose Arias é apaixonado por tecnologias relacionadas à pesquisa e big data, especialmente aquelas usadas na análise de dados.  Ele é um desenvolvedor sênior da Accenture Search & Content Analytics. https://www.linkedin.com/in/joseariasq/
Jonathan Gonzalez <(j.gonzalez.vindas@accenture.com)>
Jonathan Gonzalez é arquiteto de gerenciamento sênior da Accenture, com mais de 18 anos de experiência em desenvolvimento e design de software, e nos últimos 13 especializado em recuperação de informações, pesquisa empresarial, processamento de dados e análise de conteúdo. https://www.linkedin.com/in/jonathan-gonzalez-vindas-ba3b1543/