- Introdução
- Composição repositório
- Elaborando os conceitos básicos do sistema de buscas
- Criando o formulário no symfony
- Criando o servidor com Kibana
- Integrando o elasticsearch
- Integrando o symfony com elasticsearch
- Porque usar elasticsearch para sistemas de busca?
Introdução
Desenvolvimento de um sistema de buscas utilizando o elasticsearch. Elasticsearch é uma ferramenta de buscas, utilizada por grandes empresas coomo shopify, uber e udemy, pelo seu excelente desempenho em questões de velocidade.
Obs: esse projeto foi desenvolvido no MAC. Usuários usando outros tipos de sistema operacional devem ajustar alguns comandos durante o andamento desse projeto.
Composição repositório
Primeiro, iniciaremos um projeto com o framework symfony para agilizar processos essenciais, como roteador, controladores e views.
composer create-project symfony/skeleton:"6.1.*" search-engine
cd search-engine
composer require webapp
Uma vez que o repositório foi instalado com sucesso, podemos começar desenvolvendo o sistema de buscas.
Elaborando os conceitos básicos do sistema de buscas
O framework symfony fornece diversas ferramentas que agilizam a criação de arquivos como controladores e views. Para termos acesso a essas ferramentas, baixamos o Symfony CLI:
brew install symfony-cli/tap/symfony-cli
Uma vez que instalamos a ferramenta acima com sucesso, obtemos a habilidade de criar vários tipos de arquivos através do terminal, economizando tempo.
Para checar os comandos disponíveis, executamos o comando abaixo:
symfony console list make
Em seguida, criamos o controlador:
symfony console make:controller SearchController
O comando acima irá gerar o controlador e o arquivo de visualização web. Para verificarmos o resultado, criamos o servidor local com o comando abaixo:
symfony server:start
Para sabermos qual é o path para o controlador que criamos, executamos o comando abaixo, responsável por imprimir no terminal todos os paths que podemos acessar:
php bin/console debug:router
Já temos um view predefinido pelo symfony como na imagem abaixo:

Usando bootstrap para melhorar o visual
Para facilitar mais ainda a administração de recursos, instalamos mais uma extensão e aplicamos.
composer require symfony/webpack-encore-bundle
npm install
Bootstrap é uma biblioteca de front-end com componentes já prontos para utilização. Uma vez que instalamos e importamos o bootstrap, temos acesso a esses componentes.
npm install bootstrap --save-dev
Após instalar o bootstrap, temos que importar-lo em assets/app.js. Antes de importar, também criamos um arquivo sass global em assets/styles/global.scss.
// assets/styles/global.scss
@import "~bootstrap/scss/bootstrap";
Em seguida importamos o arquivo que importa bootstrap para podermos utilizar o bootstrap.
// assets/app.js
import './styles/global.scss';
Caso não haja problemas, concluímos compilando os arquivos css e js com o comando abaixo:
npm run dev
Caso haja erros no comando acima, instalamos o compilador de sass e ativamos carregador de sass.
npm install [email protected]^13.0.0 sass --save-dev
Ativando o carregador de sass no symfony:
// webpack.config.js
...
// enables Sass/SCSS support
.enableSassLoader() //
Quando o comando “npm run dev” for executado com sucesso, adicionamos o bootstrap para podermos usar-lo:
// templates/base.html.twig
<body>
{% form_theme form 'bootstrap_5_layout.html.twig' %}
...
</body>
Assim, finalmente podemos criar um formulário para o sistema de busca.
Criando o formulário no symfony
No symfony existem outras formas de exibir um formulário. Nesse projeto, iremos fazer isso usando o PHP.
Dentro do nosso controlador, modificamos o código dentro da função “index”:
#[Route('/search', name: 'app_search')]
public function index(Request $request): Response
{
$form = $this->createFormBuilder()
->add('keyword', TextType::class, [
'label' => 'Digite aqui para pesquisar',
'attr' => [
'placeholder' => 'Digite aqui para pesquisar',
],
'row_attr' => [
'class' => 'form-floating',
],
])
->add('submit', SubmitType::class, ['label' => 'Pesquisar'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
// TODO: Integrar após instalar o elasticsearch
}
return $this->renderForm('search/search.html.twig', [
'form' => $form,
]);
}
Em seguida, invocamos o formulário da seguinte maneira:
// templates/search/search.html.twig
{{ form(form) }}
Se tudo ocorrer como esperado, teremos o formulário abaixo:

Criando o servidor com Kibana
O kibana pode ser integrado ao elasticsearch para visualizar dados de várias formas analíticas.
Kibana pode ser instalado em um computador e ter acesso aos dados do elasticsearch de forma remota.
O ambiente de kibana pode ser criado de várias maneiras, como virtualização ou em uma máquina física separada. Nesse projeto iremos utilizar uma máquina física, o raspberrypi4.
Instalando kibana no raspberrypi4
A instalação será feita através do SSH.
ssh [email protected]
A arquitetura da máquina deve ser levada em consideração. Se instalarmos a versão errada, não teremos êxito em executar kibana.
[email protected]:/# uname -a
Linux raspberrypi 5.15.61-v8+ #1579 SMP PREEMPT Fri Aug 26 11:16:44 BST 2022 aarch64 GNU/Linux
Instalaremos kibana como escrito no documento oficial. Como vimos acima, a arquitetura da minha máquina é aarch64 debian. Os comandos executados para a instalação de Kibana estão escritos abaixo:
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
sudo apt-get install apt-transport-https
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt-get update && sudo apt-get install kibana
Após a instalação, temos que configurar Kibana para permitir acesso remoto, uma vez que vamos fazer o acesso através do raspberrypi.
nano /etc/kibana/kibana.yml
...
server.port: 5601
server.host: "0.0.0.0"
As duas variáveis devem ser o bastante para obtermos acesso remoto ao Kibana. Quando acesso meu raspberrypi através da porta 5601, consigo acessar kibana remotamente sem problemas.

Integrando o elasticsearch
Primeiramente, instalaremos o elasticsearch no computador. Nesse projeto estou usando mac, então estarei baixando conforme os documentos oficiais do elasticsearch dizem.
Se tudo ocorrer corretamente, podemos executar o elasticsearch no diretório onde ele se encontra com o comando abaixo:
./bin/elasticsearch
O comando acima estará funcionando no localhost, geralmente na porta 9200. Pelo fato do elasticsearch estar usando o protocolo SSL para segurança, teremos que acrescentar o “s” no protocolo http.
https://localhost:9200/
Na primeira vez que acessamos o endereço acima, será perguntado o usuário e a senha. Para definirmos a senha executamos o seguinte comando no diretório do elasticsearch:
bin/elasticsearch-setup-passwords interactive
Em seguida, teremos que definir senhas para múltiplos usuários já definidos de padrão.
Após definir a senha, podemos acessar o localhost. Se tivermos sucesso, dados em formato Json irão aparecer na tela.
{
"name" : "xxxxx.local",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "SQcQ2dfa2123qwUxJDVC4Q",
"version" : {
"number" : "8.4.3",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "42f05b9372a9fdsafad327899b99a76ee73",
"build_date" : "2022-10-04T07:17:24.662462378Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
Em seguida, geramos a chave de integração com Kibana executando a instrução abaixo no terminal:
bin/elasticsearch-create-enrollment-token --scope kibana
Um token deve ser imprimido no terminal. Copiamos e colamos esse token no kibana. Uma janela irá abrir perguntando o código de confirmação do Kibana. Podemos obter esse código com o seguinte comando:
journalctl -u kibana.service
Procuraremos por um log parecido com ao de baixo:
Oct 18 15:33:49 raspberrypi kibana[2116]: Your verification code is: 555 234
Copiamos e colamos o código de confirmação no Kibana e finalmente conseguimos acessar a tela de login. Entramos com o usuário chamado “elastic” e com a senha que definimos algumas etapas anteriores.

Integrando o symfony com elasticsearch
O elasticsearch já disponibiliza vários repositórios de integração de linguagens de programação. No nosso caso, estamos usando PHP e o framework Symfony, portanto estaremos usando o repositório de elasticsearch para PHP.
Continuando a implementação que tínhamos deixado pela metade, iremos primeiramente instalar a extensão de elasticsearch.
composer require elasticsearch/elasticsearch
Adicionaremos uma nova função no controlador que irá conter o algoritmo responsável por se conectar e pesquisar no elasticsearch a palavra chave que estamos procurando.
private function runElasticSearch(array $data) {
$client = ClientBuilder::create()
->setHosts(['https://localhost:9200'])
->setBasicAuthentication('elastic', 'elastic')
->setCABundle($_ENV['ELASTIC_HTTP_CA_PATH'])
->build();
// Info API
return $client->search($data);
}
Antes de começar a procurar os dados, precisamos primeiro adicionar os dados. Por essa razão, precisamos da tela de registro de documentos.
Estaremos adicionando a tela de registro no mesmo controlador da tela de busca. O algoritmo responsável por adicionar dados ao elasticsearch é o mesmo do repositório oficial.
private function indexDocument(array $data): Elasticsearch|Promise {
$client = ClientBuilder::create()
->setHosts(['https://localhost:9200'])
->setBasicAuthentication('elastic', 'elastic')
->setCABundle($_ENV['ELASTIC_HTTP_CA_PATH'])
->build();
return $client->index($data);
}
Na tela de buscas, se obtermos como resultado as informações que adicionamos anteriormente na tela de registro, tivemos sucesso.

Porque usar elasticsearch para sistemas de busca?
Elasticsearch permite a busca, registro, apagamento e análise dos dados. O sistema de busca dessa ferramenta é extremamente rápido mesmo com grande volume de dados, chegando quase na velocidade em tempo real.
Porém, elasticsearch não é tão veloz assim no registro de dados. Por essa razão, elasticsearch não substituí banco de dados tradicionais como Mysql e MongoDB, sendo um banco de dados especializado para buscas.