Documentação de Busca com Elasticsearch
Visão Geral
A loja pode usar o Elasticsearch como motor de busca de produtos. 🔍
Com a integração ativa, a busca da vitrine consulta o índice do Elasticsearch para encontrar os produtos. A plataforma continua responsável pela listagem, pelos dados comerciais, pela disponibilidade e pela ordenação final.
As rotas desta seção preparam o índice, enviam os produtos, consultam o índice e mostram os números das buscas da loja.
Rotas Disponíveis
- Sincronização do template (
POST /integrations/elasticsearch/sync/template): envia os sinônimos, cria o índice e registra o template de busca. 🧩 - Sincronização de produtos (
POST /integrations/elasticsearch/sync/products): envia produtos para o índice. 📦 - Sincronização de sinônimos (
POST /integrations/elasticsearch/sync/synonyms): envia os grupos de sinônimos ao Elasticsearch. 🔤 - Recriação do índice (
POST /integrations/elasticsearch/index/recreate): apaga o índice, cria de novo e reenvia os produtos. 🔁 - Consulta de documentos (
POST /integrations/elasticsearch/search): consulta os documentos do índice. 🔍 - Números das buscas (
GET /integrations/elasticsearch/analytics): mostra os números das buscas da loja em 1, 3 ou 5 dias. 📊
As rotas de sincronização e a de recriação gravam no índice. Elas exigem os escopos SYSTEM_CONFIGURATION_READ e SYSTEM_CONFIGURATION_WRITE. 🔒
As rotas de consulta e de números das buscas exigem apenas o escopo SYSTEM_CONFIGURATION_READ.
Regras da Busca
A busca da loja segue regras salvas nas configurações da loja. Consulte a documentação de Configurações para alterar os valores.
Cada regra tem um passo para valer na busca:
| Regra | Como aplicar |
|---|---|
Sinônimos (elasticsearch/synonyms) | Rota de sincronização de sinônimos. |
Pesos por marca e categoria (elasticsearch/boosts) | Rota de sincronização do template. |
Template da busca (elasticsearch/template) | Rota de sincronização do template. |
Produtos fixados (elasticsearch/pinned-products) | Nenhum. A regra vale em toda busca. A sincronização do template valida a regra. |
Termos priorizados (elasticsearch/prioritized-terms) | Nenhum. A regra vale em toda busca. A sincronização do template valida a regra. |
| Estrutura do índice | Rota de recriação do índice. |
Fluxo de Primeira Configuração
1. Ative a integração e informe o servidor e o nome do índice nas configurações da loja.
2. Chame a sincronização do template para criar o índice e registrar o template de busca.
3. Chame a sincronização de produtos para enviar os produtos.
4. Consulte os documentos para validar o resultado.
Política Comercial
Todas as rotas de sincronização aceitam tradePolicyId. Sem esse campo, a rota usa o valor 0. O valor 0 usa as configurações padrão da loja.
Notas e Considerações
A rota index/recreate apaga o índice. A busca fica sem produtos até o reenvio terminar. 🚨
O envio de produtos roda em segundo plano. A resposta true confirma que o envio foi iniciado, não que ele terminou.
O dashboard guarda poucos dias de histórico. Por isso ele aceita só 1, 3 ou 5 dias.
Sincronização do Template do Elasticsearch
/integrations/elasticsearch/sync/template
Prepara o Elasticsearch para a busca da loja.
Descrição
Este endpoint prepara o Elasticsearch para receber produtos e buscas.
Ele executa cinco passos, nesta ordem:
1. Valida as regras de produtos fixados e termos priorizados.
2. Envia os sinônimos da loja.
3. Cria o índice, quando ele ainda não existe.
4. Registra o template de busca, com os pesos de marca e categoria da loja.
5. Prepara o registro das buscas da vitrine, usado pelo dashboard.
Execute este endpoint depois de alterar o template da busca ou os pesos de marca e categoria.
O acesso exige autenticação UserAuth e os escopos SYSTEM_CONFIGURATION_READ e SYSTEM_CONFIGURATION_WRITE. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
tradePolicyId | integer | ❌ | ID da política comercial. Mínimo 0. Sem o campo, o valor é 0 (padrão). |
Exemplo de Requisição
1curl --request POST \2 --url {{MAIN_URL}}/integrations/elasticsearch/sync/template \3 --header "Authorization: Bearer SEU_TOKEN_AQUI" \4 --header "Content-Type: application/json" \5 --data '{6 "tradePolicyId": 07 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": true4}O campo data vale false quando o Elasticsearch recusa o registro do template. Nesse caso, o índice e os sinônimos já foram enviados. Corrija a causa e execute o endpoint de novo.
⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_CORE_INVALID_TRADE_POLICY_ID | 400 | A política comercial não pertence à loja. |
| UAPPI_STORE_ELASTICSEARCH_NOT_ACTIVE | 400 | A integração com o Elasticsearch não está ativa. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_SYNONYMS | 400 | A configuração de sinônimos é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PINNED_PRODUCTS | 400 | A configuração de produtos fixados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PRIORITIZED_TERMS | 400 | A configuração de termos priorizados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_BOOSTS | 400 | Os pesos de marca e categoria são inválidos. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_SYNC_SYNONYMS | 500 | O Elasticsearch recusou o envio dos sinônimos. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_CREATE_INDEX | 500 | O Elasticsearch não criou o índice. |
Sincronização de Produtos no Elasticsearch
/integrations/elasticsearch/sync/products
Inicia, em segundo plano, o envio de produtos para o índice.
Descrição
Este endpoint inicia o envio de produtos para o índice do Elasticsearch.
Sem productIds, o envio cobre todos os produtos elegíveis da política comercial. Com productIds, o envio cobre apenas os produtos informados.
Este endpoint não prepara o índice. Em uma loja nova, execute sync/template antes. Sem o índice preparado, a busca não funciona como configurada: ela perde os sinônimos e o tratamento de acentos.
O envio roda em segundo plano. A resposta confirma que o envio foi iniciado. Ela não confirma que o envio terminou. ⏳
A cada produto, o documento do índice recebe os dados de busca: nome, SKU, descrições, marca (id e nome), categorias (ids, nomes e caminho) e atributos.
O acesso exige autenticação UserAuth e os escopos SYSTEM_CONFIGURATION_READ e SYSTEM_CONFIGURATION_WRITE. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
tradePolicyId | integer | ❌ | ID da política comercial. Sem o campo, o valor é 0 (padrão). |
productIds | array | ❌ | Lista de produtos a enviar. Sem o campo, o envio cobre todos os produtos. |
productIds.* | integer | ✅ | ID do produto. Obrigatório para cada item da lista. |
Exemplo de Requisição
1curl --request POST \2 --url {{MAIN_URL}}/integrations/elasticsearch/sync/products \3 --header "Authorization: Bearer SEU_TOKEN_AQUI" \4 --header "Content-Type: application/json" \5 --data '{6 "tradePolicyId": 0,7 "productIds": [123, 124]8 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": true4}⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_CORE_INVALID_TRADE_POLICY_ID | 400 | A política comercial não pertence à loja. |
| UAPPI_STORE_ELASTICSEARCH_NOT_ACTIVE | 400 | A integração com o Elasticsearch não está ativa. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
Sincronização de Sinônimos no Elasticsearch
/integrations/elasticsearch/sync/synonyms
Envia os grupos de sinônimos da configuração para o Elasticsearch.
Descrição
Este endpoint lê a configuração elasticsearch/synonyms e envia os grupos ao Elasticsearch.
Os sinônimos passam a valer na busca sem reenviar os produtos.
Cada grupo da configuração segue um destes formatos:
| Tipo | Campos | Efeito |
|---|---|---|
equivalent | terms | Todos os termos do grupo valem entre si. |
directional | terms, targets | Os termos buscados passam a encontrar também os alvos. |
1{2 "groups": [3 { "type": "equivalent", "terms": ["tênis", "sapatilha esportiva"] },4 { "type": "directional", "terms": ["celular"], "targets": ["smartphone"] }5 ]6}Uma regra inválida gera erro e nada é enviado.
O acesso exige autenticação UserAuth e os escopos SYSTEM_CONFIGURATION_READ e SYSTEM_CONFIGURATION_WRITE. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
tradePolicyId | integer | ❌ | ID da política comercial. Mínimo 0. Sem o campo, o valor é 0 (padrão). |
Exemplo de Requisição
1curl --request POST \2 --url {{MAIN_URL}}/integrations/elasticsearch/sync/synonyms \3 --header "Authorization: Bearer SEU_TOKEN_AQUI" \4 --header "Content-Type: application/json" \5 --data '{6 "tradePolicyId": 07 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": true4}⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_CORE_INVALID_TRADE_POLICY_ID | 400 | A política comercial não pertence à loja. |
| UAPPI_STORE_ELASTICSEARCH_NOT_ACTIVE | 400 | A integração com o Elasticsearch não está ativa. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_SYNONYMS | 400 | A configuração de sinônimos é inválida. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_SYNC_SYNONYMS | 500 | O Elasticsearch recusou o envio dos sinônimos. |
Recriação do Índice do Elasticsearch
/integrations/elasticsearch/index/recreate
Apaga o índice, cria de novo com a estrutura atual e reenvia os produtos.
Descrição
Use este endpoint quando a estrutura do índice mudar. Um índice existente não recebe a estrutura nova sozinho. Só a recriação aplica essa estrutura.
> 🚨 Operação destrutiva. O índice é apagado. A busca fica sem produtos até o reenvio terminar.
O endpoint executa estes passos:
1. Valida as regras de produtos fixados e termos priorizados.
2. Envia os sinônimos.
3. Monta o template de busca.
4. Apaga o índice. Índice inexistente não gera erro.
5. Cria o índice com a estrutura atual.
6. Registra o template de busca.
7. Inicia, em segundo plano, o reenvio de todos os produtos.
Os passos 1 a 3 acontecem antes de apagar o índice. Uma regra de produto fixado, de termo priorizado ou de sinônimo, ou um peso inválido, interrompe a operação com o índice intacto.
Se o índice for apagado e a criação falhar, o erro UAPPI_STORE_ELASTICSEARCH_CANNOT_RECREATE_INDEX pede para executar o endpoint de novo.
O acesso exige autenticação UserAuth e os escopos SYSTEM_CONFIGURATION_READ e SYSTEM_CONFIGURATION_WRITE. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
tradePolicyId | integer | ❌ | ID da política comercial. Mínimo 0. Sem o campo, o valor é 0 (padrão). |
Exemplo de Requisição
1curl --request POST \2 --url {{MAIN_URL}}/integrations/elasticsearch/index/recreate \3 --header "Authorization: Bearer SEU_TOKEN_AQUI" \4 --header "Content-Type: application/json" \5 --data '{6 "tradePolicyId": 07 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": true4}O campo data vale false quando o Elasticsearch recusa o registro do template. Nesse caso, o índice foi recriado e o reenvio dos produtos já começou. Execute sync/template para registrar o template.
⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_CORE_INVALID_TRADE_POLICY_ID | 400 | A política comercial não pertence à loja. |
| UAPPI_STORE_ELASTICSEARCH_NOT_ACTIVE | 400 | A integração com o Elasticsearch não está ativa. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_SYNONYMS | 400 | A configuração de sinônimos é inválida. O índice continua intacto. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PINNED_PRODUCTS | 400 | A configuração de produtos fixados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PRIORITIZED_TERMS | 400 | A configuração de termos priorizados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_BOOSTS | 400 | Os pesos de marca e categoria são inválidos. O índice continua intacto. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_DELETE_INDEX | 500 | O Elasticsearch não apagou o índice. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_RECREATE_INDEX | 500 | O índice foi apagado e não foi criado de novo. Execute a recriação outra vez. |
Consulta de Documentos no Elasticsearch
/integrations/elasticsearch/search
Executa o template de busca no índice e devolve a resposta do Elasticsearch.
Descrição
Este endpoint executa o template de busca registrado no índice e devolve a resposta do Elasticsearch.
Use o endpoint para testar a relevância da busca e para inspecionar o que está indexado. A listagem de produtos da vitrine usa o mesmo motor e devolve os dados comerciais.
Regras que o endpoint aplica:
- Produtos fixados: quando o termo é exatamente o termo de uma regra de
elasticsearch/pinned-products, os produtos da regra aparecem no topo. A regra só vale comfromigual a0. Cada produto fixado traz"_pinned": true. Produto fixado que não está no índice é ignorado. - Termos priorizados: as regras de
elasticsearch/prioritized-termsreordenam o resultado quando a busca contém o termo como palavra inteira. - Sinônimos e acentos: a busca ignora acentos e aplica os sinônimos enviados.
As buscas feitas por este endpoint não entram no dashboard de busca. O dashboard registra só as buscas da vitrine. 📊
O acesso exige autenticação UserAuth e o escopo SYSTEM_CONFIGURATION_READ. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
terms | string | ✅ | Termos da busca. |
tradePolicyId | integer | ❌ | ID da política comercial. Sem o campo, o valor é 0 (padrão). |
limit | integer | ❌ | Quantidade máxima de documentos. Máximo 5000. Sem o campo, o valor é 5000. |
from | integer | ❌ | Quantidade de documentos a pular. Sem o campo, o valor é 0. |
fields | array | ❌ | Campos de cada documento na resposta. Sem o campo, a resposta traz o documento completo. |
fields.* | string | ✅ | Nome de um campo do documento. |
Exemplo de Requisição
1curl --request POST \2 --url {{MAIN_URL}}/integrations/elasticsearch/search \3 --header "Authorization: Bearer SEU_TOKEN_AQUI" \4 --header "Content-Type: application/json" \5 --data '{6 "terms": "tenis",7 "limit": 10,8 "from": 0,9 "fields": ["name", "sku"]10 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
O campo data traz a resposta do Elasticsearch. O campo _source de cada item traz os dados do produto indexado. O parâmetro fields limita esses dados.
1{2 "status": true,3 "data": {4 "took": 4,5 "timed_out": false,6 "hits": {7 "total": { "value": 2, "relation": "eq" },8 "max_score": 31.2,9 "hits": [10 {11 "_id": "123",12 "_score": null,13 "_source": { "name": "Tênis Corrida", "sku": "TEN-001" },14 "_pinned": true15 },16 {17 "_id": "124",18 "_score": 31.2,19 "_source": { "name": "Tênis Casual", "sku": "TEN-002" }20 }21 ]22 }23 }24}O campo _id é o ID do produto na plataforma.
⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_STORE_ELASTICSEARCH_NOT_ACTIVE | 400 | A integração com o Elasticsearch não está ativa. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PINNED_PRODUCTS | 400 | A configuração de produtos fixados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PRIORITIZED_TERMS | 400 | A configuração de termos priorizados é inválida. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_SEARCH | 500 | O Elasticsearch não executou a busca. |
Números das Buscas da Loja
/integrations/elasticsearch/analytics
Agrega os registros de busca da loja no período, para o dashboard de busca.
Descrição
Este endpoint agrega os registros de busca da loja e alimenta o dashboard de busca. 📊
O período aceita 1, 3 ou 5 dias, contando o dia de hoje. Os dias seguem o fuso America/Sao_Paulo.
A plataforma guarda poucos dias de histórico. Por isso o período aceita só esses valores.
Sem registro no período, a resposta traz os números zerados e todos os dias do período.
A comparação de tendência usa o período anterior de mesma duração. Quando o período anterior inteiro já foi apagado, hasTrend vale false e trend vale null.
O dashboard funciona também com a integração desativada, desde que o servidor e o índice estejam informados.
O acesso exige autenticação UserAuth e o escopo SYSTEM_CONFIGURATION_READ. 🔒
Parâmetros
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros de Query
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
days | integer | ✅ | Período em dias. Valores aceitos: 1, 3 e 5. |
tradePolicyId | integer | ❌ | ID da política comercial. Mínimo 0. Sem o campo, o valor é 0 (padrão). |
Exemplo de Requisição
1curl --request GET \2 --url "{{MAIN_URL}}/integrations/elasticsearch/analytics?days=3&tradePolicyId=0" \3 --header "Authorization: Bearer SEU_TOKEN_AQUI"✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": {4 "days": 3,5 "hasTrend": true,6 "totals": {7 "searches": 120,8 "uniqueTerms": 45,9 "zeroResults": 8,10 "byDriver": { "elastic": 100, "internal": 20 }11 },12 "daily": [13 { "date": "2026-10-17", "searches": 30, "zeroResults": 2 },14 { "date": "2026-10-18", "searches": 40, "zeroResults": 3 },15 { "date": "2026-10-19", "searches": 50, "zeroResults": 3 }16 ],17 "topTerms": [18 { "term": "tênis", "searches": 25, "avgResults": 12.4, "zeroResults": 0, "trend": "up" }19 ],20 "zeroResultTerms": [21 { "term": "chinelo xyz", "searches": 4, "lastSeen": "2026-10-19T14:32:10-03:00" }22 ]23 }24}Campos da resposta
| Campo | Tipo | Descrição |
|---|---|---|
days | integer | Período pedido. |
hasTrend | boolean | Indica se o período anterior inteiro ainda existe e permite comparar. |
totals.searches | integer | Total de buscas no período. |
totals.uniqueTerms | integer | Quantidade de termos diferentes, sem acento, caixa e pontuação. |
totals.zeroResults | integer | Buscas sem resultado. |
totals.byDriver | object | Buscas atendidas pelo Elasticsearch (elastic) e pela busca interna da plataforma (internal). |
daily[] | array | Um item por dia do período. |
daily[].date | string | Dia no formato Y-m-d. |
daily[].searches | integer | Buscas do dia. |
daily[].zeroResults | integer | Buscas sem resultado do dia. |
topTerms[] | array | Até 20 termos mais buscados. |
topTerms[].term | string | Forma mais buscada do termo. |
topTerms[].searches | integer | Buscas do termo. |
topTerms[].avgResults | number | Média de resultados por busca, com uma casa decimal. |
topTerms[].zeroResults | integer | Buscas do termo sem resultado. |
topTerms[].trend | string ou null | new, up, down ou flat. null sem comparação. Variação até 10% vale flat. |
zeroResultTerms[] | array | Até 20 termos sem resultado. |
zeroResultTerms[].term | string | Forma mais buscada do termo. |
zeroResultTerms[].searches | integer | Buscas do termo sem resultado. |
zeroResultTerms[].lastSeen | string | Data e hora da última busca, no formato ISO 8601. |
⚠️ Possíveis erros:
| Código Interno | Código Http | Descrição |
|---|---|---|
| UAPPI_CORE_INVALID_TRADE_POLICY_ID | 400 | A política comercial não pertence à loja. |
| UAPPI_STORE_ELASTICSEARCH_INVALID_PERIOD | 400 | O período precisa ser 1, 3 ou 5 dias. |
| UAPPI_STORE_ELASTICSEARCH_NOT_CONFIGURED | 400 | A integração não está configurada. |
| UAPPI_STORE_ELASTICSEARCH_CANNOT_SEARCH | 500 | O Elasticsearch não executou a consulta. |