Como construir grandes experiências de pesquisa com rapidez

Jason Stoltzfus em codeburst Segue 9 de jul · 13 min ler A pesquisa da interface do usuário e a Pesquisa do aplicativo Elastic tornam a adição de pesquisa a um aplicativo do React rápida e fácil.

Construir experiências de pesquisa é um trabalho árduo. Pode parecer fácil: criar uma barra de pesquisa, colocar dados em um banco de dados e, em seguida, fazer consultas de combustível de entrada do usuário no banco de dados. Mas há muitas coisas a serem consideradas na modelagem de dados, na lógica subjacente e, é claro, no design geral e na experiência do usuário.

Vamos explicar como criar excelentes experiências de pesquisa baseadas no React usando a biblioteca de UI de pesquisa de código aberto do Elastic . Isso levará cerca de 30 minutos e, depois, você estará pronto para levar a pesquisa a qualquer aplicativo.

Mas primeiro, o que torna a pesquisa de edifícios tão desafiadora?

A pesquisa é difícil

Um ótimo artigo fez as rondas algumas semanas atrás intitulado Falsehoods Programmers Believe About Search . Ele contém uma lista exaustiva de falsas suposições que os desenvolvedores levam para o desenvolvimento da pesquisa.

Entre os muitos acreditavam falsidades:

  • "Os clientes que sabem o que estão procurando pesquisam da maneira que você espera"
  • "Você pode escrever um analisador de consulta que sempre analisará a consulta com êxito"
  • "Depois da configuração, a pesquisa funcionará da mesma forma na próxima semana"
  • "Sinônimos são fáceis"
  • … E muitas outras jóias – você deve dar uma lida!

A conclusão é que a pesquisa tem muitos desafios – e eles não estão apenas sob o capô. Você precisa pensar em como gerenciar o estado, criar componentes para filtragem, lapidação, classificação, paginação, sinônimos, processamento de idioma e muito, muito… muito mais. Mas, em resumo:

A criação de uma ótima pesquisa requer duas partes sofisticadas: (1) o mecanismo de pesquisa, que fornece APIs para ativar a pesquisa e (2) a biblioteca de pesquisa, que pinta a experiência de pesquisa .

Para o mecanismo de pesquisa , veremos a Elastic App Search .

Para a experiência de pesquisa , introduziremos uma biblioteca de pesquisa do sistema operacional: a interface de pesquisa .

Quando terminarmos, vai parecer assim :

Search Engine: Elastic App Search

A Pesquisa de aplicativos está disponível como um serviço pago e gerenciado ou como uma distribuição autogerenciada gratuita . Usaremos o serviço gerenciado para este tutorial, mas lembre-se de que sua equipe pode usar a interface do usuário de pesquisa e a Pesquisa de aplicativos com uma licença básica , sem custos, caso você a hospede por conta própria .

O plano: indexar documentos que representam os melhores videogames de todos os tempos em um mecanismo de pesquisa e, em seguida, projetar e otimizar uma experiência de pesquisa para pesquisá-los.

Primeiro, inscreva-se para um teste de 14 dias – sem necessidade de cartão de crédito.

Crie um mecanismo. Você pode escolher entre 13 idiomas diferentes.

Vamos chamá-lo de video-games e definir o idioma para o inglês.

Faça o download do melhor conjunto de dados de videogames e envie-o para a Pesquisa de aplicativos usando o importador.

Em seguida, clique no mecanismo e selecione a guia Credenciais .

Crie uma nova chave de pesquisa pública com acesso limitado ao mecanismo somente ao mecanismo de video-games de video-games .

Recupere a nova chave de pesquisa pública e seu identificador de host .

Mesmo que não pareça muito, agora temos um mecanismo de pesquisa em pleno funcionamento que está pronto para pesquisar nossos dados de videogame usando uma API de pesquisa refinada.

Aqui está o que fizemos até agora:

  • Criado um mecanismo de pesquisa.
  • Documentos ingeridos.
  • Criado um esquema padrão.
  • Recuperou uma credencial descartável e com escopo definido que podemos expor ao navegador.

É isso para App Search, por enquanto.

Vamos começar a criar nossa experiência de pesquisa usando a interface de pesquisa.

Biblioteca de pesquisa: interface de pesquisa

Vamos usar o utilitário create-react-app scaffolding para criar um aplicativo React:

 npm install -g criar-reagir-app 
criar-reagir-app video-game-search - usar-npm
cd video-game-search

Nesta fundação, instalaremos a interface de pesquisa e o conector da pesquisa de aplicativos:

 npm install - save @ elastico / react-search-ui @ elastico / search-ui-app-search-connector 

E inicie o aplicativo no modo de desenvolvimento:

 npm start 

Abra o src/App.js no seu editor de texto favorito.

Vamos começar com algum código clichê e depois descompactá-lo.

Mente os comentários!

 // Etapa # 1, importar instruções de importação Reagir de "reagir"; 
import AppSearchAPIConnector de "
@ elástico / busca-ui-app-busca- connector ";
import {SearchProvider, Results, SearchBox} de "
@ elastic / react-search-ui ";
import {Layout} de "
@ elastic / react-search-ui-views ";
importação "
@ elastic / react -search-ui-views /lib/styles/styles.css ";
// Etapa 2, Conector const do Conector = novo AppSearchAPIConnector ({
searchKey: "[YOUR_SEARCH_KEY]",
engineName: "video-games",
hostIdentifier: "[YOUR_HOST_IDENTIFIER]"
});
// Passo # 3: Opções de configuração const configurationOptions = {
apiConnector: conector
// Vamos preencher isso juntos.
};
// Etapa 4, SearchProvider: os toques finais. função padrão de exportação App () {
Retorna (
<SearchProvider config = {configurationOptions}>
<div className = "App">
<Layout
// Vamos preencher isso juntos.
/>
</ div>
</ SearchProvider>
);
}

Etapa 1: instruções de importação

Precisamos importar nossas dependências da interface de pesquisa e Reagir.

Os principais componentes, conectores e componentes de visualização estão contidos em três pacotes diferentes: @elastic/search-ui-app-search-connector , @elastic/react-search-ui e @elastic/react-search-ui-views . Aprenderemos mais sobre cada um deles à medida que avançamos.

 importar Reagir de "reagir"; import AppSearchAPIConnector de " @ elástico / pesquisa-ui-app-pesquisa- conector"; import {SearchProvider, Results, SearchBox} de " @ elastic / react-search-ui "; import {Layout} de " @ elastic / react-search-ui-views "; import " @ elastico / react -search-ui-views /lib/styles/styles.css"; 

Também estaremos importando uma folha de estilo padrão para este projeto, que nos dará uma boa aparência sem escrever uma linha do nosso próprio CSS:

 import " @ elastico / react -search-ui-views /lib/styles/styles.css"; 

Etapa 2: o conector

Temos a chave de pesquisa pública e o identificador de host da Pesquisa de aplicativos.

Hora de colocá-los para trabalhar!

O objeto conector na interface de pesquisa usa as credenciais para conectar-se à pesquisa de aplicativos e à pesquisa avançada:

 conector const = novo AppSearchAPIConnector ({ 
searchKey: "[YOUR_SEARCH_KEY]",
engineName: "video-games",
hostIdentifier: "[YOUR_HOST_IDENTIFIER]"
});

A IU de pesquisa funciona com qualquer API de pesquisa . Mas os conectores fazem com que uma API de pesquisa "simplesmente funcione", sem qualquer configuração mais profunda.

Etapa 3: configurationOptions

Antes de nos aprofundarmos em configurationOptions , vamos refletir um pouco.

Nós importamos um conjunto de dados para o nosso mecanismo de busca. Mas que tipo de dados é esse?

Quanto mais soubermos sobre nossos dados, melhor entenderemos como apresentar esses dados para os pesquisadores. E isso informará como configurar a experiência de pesquisa.

Vejamos um objeto, o melhor objeto de todos dentro desse conjunto de dados:

 { 
"id": "final-fantasia-vii-ps-1997",
"nome": "Final Fantasy VII",
"ano": 1997,
"plataforma": "PS",
"gênero": "Role-Playing",
"publisher": "Sony Computer Entertainment",
"global_sales": 9,72,
"critic_score": 92,
"user_score": 9,
"desenvolvedor": "SquareSoft",
"imagem URL": "
https://r.hswstatic.com/w_907/gif/finalfantasyvii-MAIN.jpg "
}

Vemos que ele possui vários campos de texto, como name , year , platform e assim por diante, além de alguns campos numéricos como critic_score , global_sales e user_score .

Se fizermos três perguntas importantes, saberemos o suficiente para construir uma sólida experiência de pesquisa:

  1. Como a maioria das pessoas pesquisará? Pelo nome do video game.
  2. O que a maioria das pessoas quer ver em um resultado? O nome do videogame, seu gênero, editor, partituras e sua plataforma.
  3. Como a maioria das pessoas irá filtrar, classificar e facetar? Por pontuação, gênero, editor e plataforma.

Podemos, então, traduzir essas respostas em nossas configurationOptions :

 const configurationOptions = { 
apiConnector: conector,
consulta de pesquisa: {
search_fields: {
// 1. Pesquise por nome de videogame. nome: {}
}
// 2. Resultados: nome do video game, seu gênero, editor, partituras e plataforma. result_fields: {
name: {
// Um snippet significa que os termos de pesquisa correspondentes serão destacados por meio de tags <em>.
snippet: {
size: 75, // Limite o trecho para 75 caracteres.
fallback: true // Retorna para um resultado "bruto".
}
}
gênero: {
snippet: {
tamanho: 50,
fallback: true
}
}
editor: {
snippet: {
tamanho: 50,
fallback: true
}
}
critic_score: {
// As pontuações são numéricas, portanto, não tentaremos snippet-las, apenas usaremos as
// valor.
cru: {}
}
user_score: {
cru: {}
}
plataforma: {
snippet: {
tamanho: 50,
fallback: true
}
}
imagem URL: {
cru: {}
}
}
// 3. Facetado por pontuações, gênero, editor e plataforma, que usaremos para criar filtros posteriormente. facetas: {
user_score: {
tipo: "intervalo",
gamas: [
{de: 0 a: 5, nome: "não bom"},
{de: 5, a: 7, nome: "Nada mau"},
{de: 7, a: 9, nome: "Muito bom"},
{de: 9, a: 10, nome: "Deve jogar!" }
]
}
critic_score: {
tipo: "intervalo",
gamas: [
{de: 0 a 50: nome: "não bom"},
{de: 50, a: 70, nome: "Nada mau"},
{de: 70, a: 90, nome: "Muito bom"},
{de: 90, para: 100, nome: "Deve jogar!" }
]
}
gênero: {type: "value", tamanho: 100},
editor: {type: "value", size: 100},
plataforma: {type: "value", size: 100}
}
}
};

Conectamos a interface de pesquisa ao nosso mecanismo de pesquisa e agora temos opções que determinam como pesquisaremos dados, exibiremos nossos resultados e, em seguida, exploraremos esses resultados. Mas precisamos de algo para vincular tudo aos componentes front-end dinâmicos da interface de pesquisa.

Etapa 4: SearchProvider

O objeto que governa todos eles; o SearchProvider é onde todos os outros componentes são aninhados.

A UI de pesquisa fornece um componente Layout , que é usado para pintar um layout típico de pesquisa. Existem opções de personalização profundas, mas não vamos entrar naquelas neste tutorial.

Vamos fazer duas coisas:

  1. Passe em configurationOptions para SearchProvider .
  2. Coloque alguns blocos estruturais no Layout e adicione dois componentes básicos: SearchBox e Results .
 função padrão de exportação App () { 
Retorna (
<SearchProvider config = {configurationOptions}>
<div className = "App">
<Layout
header = {<SearchBox />}
// titleField é o campo mais proeminente em um resultado: o cabeçalho do resultado.
bodyContent = {<Resultados titleField = "nome" urlField = "image_url" />}
/>
</ div>
</ SearchProvider>
);
}

Depois que essas alterações forem salvas, vamos cutucar o ambiente do desenvolvedor local. A primeira coisa que surge é que estamos perdendo ferramentas para explorar nossos resultados, como filtragem, lapidação, classificação… Mas a pesquisa funciona. Tente algumas perguntas!

Precisamos detalhar a interface do usuário. E precisamos trabalhar no modelo de relevância para que a pesquisa seja bem ajustada para as necessidades exclusivas desse projeto.

Desativar a pesquisa de aplicativos ~

De volta ao laboratório

A Pesquisa de aplicativos possui recursos poderosos e refinados do mecanismo de pesquisa. Torna a afinação uma vez sofisticada muito mais agradável. Podemos realizar ajustes de relevância refinados e alterações de esquema contínuas em apenas alguns cliques.

Vamos ajustar o esquema primeiro para vê-lo em ação.

Entre na Pesquisa de aplicativos , insira o mecanismo de video-games e clique em Esquema na seção Gerenciar .

O esquema aparece. Cada um dos 11 campos é considerado texto por padrão.

No objeto configurationOptions , definimos dois filtros de intervalo para nos ajudar a pesquisar os números: user_score e critic_score . Para que um filtro de intervalo funcione conforme o esperado, o tipo de campo precisa ser um número .

Também podemos querer fazer algum ajuste de aprimoramento e relevância com base em valores numéricos.

Clique no menu suspenso ao lado de cada campo, altere-o para número e clique em Tipos de atualização :

O mecanismo re-indexa em tempo real. Mais tarde, quando adicionarmos os componentes de lapidação ao nosso layout, os filtros de intervalo funcionarão como esperamos.

E agora, para o material bacana real.

Esta seção é altamente relevante

Há três principais recursos de relevância: sinônimos , curadorias e ajuste de relevância .

Selecione cada recurso na seção Configurações de pesquisa na barra lateral:

Sinônimos

Algumas pessoas dirigem carros, alguns automóveis, outros podem dirigir um calhambeque. A internet é global e as pessoas ao redor do mundo usam palavras diferentes para descrever as coisas. Os sinônimos ajudam você a criar conjuntos de termos considerados um e o mesmo.

No caso de um mecanismo de busca de videogames, sabemos que as pessoas vão querer encontrar o Final Fantasy . Mas talvez eles digitam FF em vez disso.

Clique em Sinônimos , selecione Criar um Conjunto de Sinônimo e digite os termos:

Clique em Salvar . Você pode adicionar quantos conjuntos de sinônimos desejar.

As pesquisas por FF agora terão o mesmo peso que as pesquisas por Final Fantasy .

Curadorias

As curadorias são as favoritas. O que se alguém procurar Final Fantasy ou FF? Existem muitos jogos na série – o que eles terão?

Por padrão, os cinco principais resultados são assim:

  1. Final Fantasy VIII
  2. Final Fantasy X
  3. Táticas de Final Fantasy
  4. Final Fantasy IX
  5. Final Fantasy XIII

Isso não parece certo … Final Fantasy VII foi o melhor jogo Final Fantasy de todos. E Final Fantasy XIII não foi muito bom! ?

Podemos fazer com que alguém procurando por Final Fantasy receba Final Fantasy VII como o primeiro resultado ? E podemos remover Final Fantasy XII dos nossos resultados de pesquisa ?

Podemos!

Clique em Curadorias e insira uma consulta: Final Fantasy .

Em seguida, arraste o documento Final Fantasy VII para a seção Documentos Promovidos , segurando o guidão no lado mais à esquerda da tabela. E então clique no botão Hide Result no documento Final Fantasy XIII – o olho com a linha passando por ele:

Qualquer pessoa que esteja fazendo uma busca por Final Fantasy ou FF verá agora Final Fantasy VII primeiro.

… E eles não verão Final Fantasy XIII. Hah!

Nós podemos promover e esconder muitos documentos. Podemos até classificar os documentos promovidos para mantermos controle total sobre o que aparece no topo de cada consulta.

Ajuste de Relevância

Clique em Relevance Tuning na barra lateral.

Nós pesquisamos em um campo de texto: o campo do name . Mas e se tivermos vários campos de texto que as pessoas pesquisarão, como um campo de name e um campo de description ? O conjunto de dados de videogame que estamos usando não contém um campo de descrição, por isso, vamos fingir alguns documentos para pensar nele.

Digamos que nossos documentos parecessem semelhantes a isso:

 { 
"name": "Magical Quest",
"description": "Uma jornada perigosa pelas cavernas e coisas assim."
}
{
"name": "Dangerous Quest",
"description": "Uma jornada mágica cheia de magia mágica. Altamente mágica."
}

Se alguém quisesse encontrar o jogo Magical Quest , eles entrariam nessa como a consulta. Mas o primeiro resultado seria Missão Perigosa :

Por quê? Porque a palavra “mágica” está presente três vezes na descrição de Dangerous Quest e o mecanismo de busca não saberá que um campo é mais importante que outro. Então, ele classificará a Dangerous Quest mais alta. Este enigma é porque existe o Relevance Tuning .

Podemos selecionar um campo e – entre outras coisas – aumentar a ponderação de sua relevância:

Vemos que quando aumentamos o peso, o item certoMissão Mágica – sobe ao topo porque o campo do name se torna mais significativo. Tudo o que precisamos fazer é arrastar o controle deslizante para um valor mais alto e clicar em Salvar .

Agora, usamos a Pesquisa de aplicativos para:

  1. Ajuste o esquema e altere user_score e critic_score para campos numéricos .
  2. Ajuste o modelo de relevância.

E isso conclui os sofisticados recursos do "painel" – cada um deles tem um ponto de extremidade de API correspondente que você pode usar para fazer as coisas funcionarem de maneira programática se as GUIs não forem o seu objetivo.

Agora vamos terminar a interface do usuário.

Toques finais

Dentro do arquivo src/App.js inicial, nós importamos três componentes básicos:

 import {SearchProvider, Results, SearchBox} de " @ elastic / react-search-ui "; 

Vamos adicionar um pouco mais, dado o que definimos para nossas opções de configuração.

A importação dos seguintes componentes ativará as habilidades ausentes na interface do usuário:

  • PagingInfo : Exibe informações na página atual.
  • ResultsPerPage : Configure quantos resultados aparecem em cada página.
  • Paging : Navegue por diferentes páginas.
  • Facet : filtre e explore os dados de maneiras exclusivas para o tipo de dados.
  • Sorting : reorientar os resultados para um determinado campo.
 importar { 
PagingInfo,
Resultados por página,
Paginação,
Faceta,
SearchProvider,
Resultados,
Caixa de pesquisa,
Classificação
} de "
@ elastic / react-search-ui ";

Uma vez importados, os componentes podem ser colocados no layout.

O componente Layout divide a página em seções e os componentes podem ser colocados nessas seções via adereços.

Contém seções para o:

  1. header : caixa de pesquisa / barra.
  2. bodyContent : Contêiner de resultados.
  3. sideContent : Barra lateral que contém facetas e opções de classificação.
  4. bodyHeader : “Wrapper” em torno de resultados com informações ricas em contexto, como a página atual, o número de resultados por página.
  5. bodyFooter : Opções de paginação para navegação rápida entre as páginas.

Componentes renderizam dados. Os dados são buscados com base nas configurações de pesquisa que fornecemos nas configurationOptions . Agora, vamos colocar cada componente na seção Layout apropriada.

Por exemplo, descrevemos 5 dimensões de facetagem em configurationOptions , portanto, criaremos 5 componentes de Facet . Cada componente Facet usará um field prop como uma chave de volta para nossos dados.

Vamos colocá-los no sideContent seção, juntamente com a nossa Sorting componente, em seguida, coloque a Paging , PagingInfo , ResultsPerPage componentes nas seções que melhores suites eles:

 <Layout 
header = {<SearchBox />}
bodyContent = {<Resultados titleField = "nome" urlField = "image_url" />}
sideContent = {
<div>
<Classificando
label = {"Classificar por"}
sortOptions = {[
{
nome: "Relevância",
valor: "",
direção: ""
}
{
nome nome",
valor: "nome",
direção: "asc"
}
]}
/>
<Facet field = "user_score" label = "Pontuação do usuário" />
<Campo da faceta = "critic_score" label = "Pontuação da crítica" />
<Campo da faceta = "gênero" label = "Gênero" />
<Campo de faceta = "editora" label = "Publicador" isFilterable = {true} />
<Campo da faceta = "plataforma" label = "Plataforma" />
</ div>
}
bodyHeader = {
<>
<PagingInfo />
<ResultsPerPage />
</>
}
bodyFooter = {<Paging />}
/>;

Agora vamos dar uma olhada na experiência de pesquisa no ambiente de desenvolvimento local.

Muito melhor! Temos opções ricas para explorar os resultados da pesquisa.

Nós adicionamos alguns extras extras, como várias opções de classificação, e tornamos a faceta do editor filtrável, adicionando uma única bandeira. Tente uma pesquisa com uma consulta em branco e explore todas as opções.

Finalmente, vamos ver um último recurso da experiência de pesquisa. É um popular…

Autocompletar.

Você me Autocompletar

Os pesquisadores adoram o preenchimento automático porque fornecem feedback instantâneo. Suas sugestões vêm em dois sabores: resultado e consulta . Dependendo do sabor, um pesquisador receberá resultados relevantes ou possíveis consultas que podem levar a resultados.

Vamos nos concentrar no preenchimento automático como uma forma de "sugestão de consulta".

Isso requer duas mudanças rápidas.

Primeiro, precisamos adicionar o autocomplete ao objeto configurationOptions :

 const configurationOptions = { 
// ...
autocompleteQuery: {
sugestões: {
types: {
documentos: {
// Quais campos procurar por sugestões.
campos: ["nome"]
}
// Quantas sugestões aparecem.
tamanho: 5
}
}
}
// ...
};

Em segundo lugar, precisamos ativar o preenchimento automático como uma função do SearchBox :

 // ... 
<Layout
// ...
header = {<SearchBox autocompleteSuggestions = {true} />}
/>
// ...

Sim – é isso.

Experimente pesquisar – conforme você digita, aparecem sugestões de consulta de preenchimento automático.

Resumo

Agora temos uma experiência de pesquisa funcional e atraente. E evitamos toda uma confusão de armadilhas que muitas vezes pegam as pessoas enquanto elas tentam implementar a pesquisa. Nada mal por 30 minutos, você não diria?

Vídeo-Jogos-Tutorial – CodeSandbox

Jogue com o tutorial finalizado no CodeSandbox

codesandbox.io