Aggregation, para lista de produtos mais pedidos em um determinado período

Aqui vamos mostrar um pouco mais de como podemos utilizar as aggregations, como dito no outro artigo sobre o assunto, as aggregations são operações onde podemos agrupar dados e gerar resultados conforme as nossas necessidades, para realizarmos algumas análise de dados da nossa loja na E-com Plus :purple_heart:.

Na nossa aggregation de hoje, vamos listar os produtos mais pedidos em um determinado período de tempo, preparados? Café está na mão :coffee:? Sim… vamos lá… :rocket: :rocket:


COMO REALIZAR A AGGREGATION


Vamos precisar de alguns dados importantes para realizarmos a nossa requisição, tais como ID da loja, ID da sua autenticação e o token. Não sabe onde encontrar esses dados? Recomendo aqui que leia nossa postagem anterior sobre aggregations : Como criar agrupamentos de dados, Aggregation, nela realizamos um passo-a-passo de como coletar as informações necessárias e como realizar uma aggregation.

De posse das informações necessárias descritas anteriormente, então vamos a nossa requisição de aggregation. Nesta requisição também iremos utilizar o Hoppscotch (https://hoppscotch.io/ ) para realizar a aggregation em nossa API :heart_eyes:.

As aggregations são uma requisições de método POST, na seguinte url: https://api.e-com.plus/v1/$aggregate.json

O Header da requisição deverá conter as seguintes informações:

  • X-Store-ID: Id_da_sua_loja
  • X-Access-Token: seu_token_atualizado
  • X-My-ID: id_da_sua_autenticacao


Por isso a importância de ter essas informações antes de realizarmos a requisição de aggregation.

Como dito na nossa outra postagem sobre aggregations, o segredos delas está no body da requisição, onde iremos passar duas propriedades: a primeira é o resource, no qual vamos informar qual collection (tabela) iremos realizar a operação e a segunda propriedade é o pipeline que é um conjunto de estágios em nossa operação.

Sobre o resource, como iremos listar os produtos mais pedidos em um determinado período de tempo, nossa operação será realizada na colletion de pedidos ou seja na orders.

O pipeline terá os seguintes estágios:

  • Primeiro estágio é:
{
 "$match": {
   "created_at": {
    "$gte": "2022-01-01T00:00:00.000Z"
   }
  }
},

que irá definir a data inicial da nossa requisição, neste exemplo estamos utilizando a data do dia 01 de Maio de 2022 para ser a data de início da nossa operação.

  • O segundo estágio é:
{
 "$match": {
   "created_at": {
    "$lte": "22022-12-31T23:59:59.999Z"
   }
  }
},

que irá definir a data final do nosso período de busca, aqui a data escolhida foi 31 de Maio de 2022.

Obs: Nestes dois primeiros estágios é que definimos o período que gostaríamos de analisar, neste exemplo usamos o período do mês de Maio, mas poderia ser qualquer período que desejássemos analisar.

  • O terceiro estágio é:
{
 "$unwind": "$items"
},

aqui nesse estágio iremos separar nosso itens do pedido, para que possamos contabilizar itens diferentes de um mesmo pedido.

  • Já o nosso quarto estágio é
{
  "$group": {
    "_id": "$items.product_id",
    "count": {
      "$sum": "$items.quantity"
     }
  }
},

um agrupamento dos itens, que serão agrupados pelo _id do produto (product_id) e será contabilizado a quantidade desse produto na propriedade count

  • Já o nosso quinto e último estágio, porém não menos importante, é a ordenação da nossa resposta que deverá ser em ordem decrescente, ou seja, os produtos com mais quantidade de pedidos estarão no topo da nossa lista de resposta.
{
  "$sort": {
    "count": -1
    }
}

Sendo assim o body da nossa requisição terá a seguinte forma:

{
  "resource": "orders",
  "pipeline": [
    {
      "$match": {
        "created_at": {
          "$gte": "2022-01-01T00:00:00.000Z"
        }
      }
    },
    {
      "$match": {
        "created_at": {
          "$lte": "2022-12-31T23:59:59.999Z"
        }
      }
    },
    {
      "$unwind": "$items"
    },
    {
      "$group": {
        "_id": "$items.product_id",
        "count": {
          "$sum": "$items.quantity"
        }
      }
    },
    {
      "$sort": {
        "count": -1
      }
    }
  ]
}


A nossa resposta terá o seguinte formato:

{
  "result": [
    {
      "_id": "6166cb1528ace502aea2dc36",
      "count": 5
    },
    {
      "_id": "5f8dd8e8b2161709fa40c620",
      "count": 1
    }
  ]
}

Ou seja, houveram 5 pedidos do produto com o _id 6166cb1528ace502aea2dc36 e 1 pedido do produto cujo o _id é 5f8dd8e8b2161709fa40c620, no período do dia 1 de maio de 2022 à 31 de maio de 2022.

Espero que este artigo possa contribuir para vocês nas análises de seus pedidos e também em como vocês podem construir suas próprias aggregations.

Até breve pessoal :raising_hand_man:t5: :purple_heart:.

4 curtidas

Boa @wisley, bom pra virar um relatório isso ai. No caso, desse agrupamento, além da soma de quantos itens foram vendidos em um determinado período, conseguimos ter o retorno do nome do produto por exemplo?

1 curtida

@Matheus , sim há algumas alternativas uma delas poderiamos, trocar o _id do estágio do $group para $items.name:

{
  "$group": {
    "_id": "$items.name",
    "count": {
      "$sum": "$items.quantity"
    }
}

outra alternativa seria adicionar o name em uma outra propriedade.

{
  "$group": {
    "_id": "$items.product_id",
    "count": {
      "$sum": "$items.quantity"
    },
    "name": {
      "$addToSet": "$items.name" 
    }
  }
}
1 curtida

boa tarde!!!

Por favor, podem me dizer como faço para criar um aggregation para listar os pedidos por estado (UF) e Cidade?
Com Itens e valor total do pedido?

Muito obg

1 curtida

Estou buscando encontrar uma melhor solução, para essa aggregation, assim que conseguir posto aqui para você.

1 curtida

@pietroembalagens bom tenho algumas opções para você caso você queira apenas listar os pedidos de uma determinada localidade, talvez não seja necessário uma aggregation uma busca mais simples já seria suficiente

Opção 1

GET https://api.e-com.plus/v1/orders.json?shipping_lines.to.province_code=MG&fields=amount,items

Aqui nesse exemplo utilizei apenas o estado, no caso MG, mas se preferir pode adicionar a cidade também:

GET https://api.e-com.plus/v1/orders.json?shipping_lines.to.province_code=MG&&shipping_lines.to.city=Belo Horizonte&fields=amount,items

OBS: Lembrando de utilizar os headers de autenticação, são os mesmos descritos aqui nesse post

Deixo aqui também o link da referência da nossa API :purple_heart:

Opção 2

Mas se sua necessidade for uma análise produtos mais vendidos em uma determinada localidade, você pode utilizar a aggregation como o seguinte body:

{
  "resource": "orders",
  "pipeline": [
    {
      "$match": {
        "created_at": {
          "$gte": "2022-01-01T00:00:00.000Z",
           "$lte": "2023-07-11T23:59:59.999Z"
        }
      }
    },
    {
        "$project":{
            "_id": 1,
            "created_at": 1,
            "items": 1,
            "to": { "$arrayElemAt": [ "$shipping_lines.to", 0 ] }
        }
    },
    {
      "$unwind": "$items"
    },
    {
         "$group": {
            "_id": { "product_id": "$items.product_id", "state": "$to.province_code"  },
            "count": { "$sum": "$items.quantity" },
            "amount": { "$sum": {"$multiply":["$items.quantity", {"$cond": [{"$gte": ["$items.final_price",0]},"$items.final_price","$items.price"]}]}}
         }
    }
  ]
}

Aqui defini para analise o inicio de 2022 até a data atual.

Caso precise definir por cidade também basta adicionar dentro do _id do $group o campo "city":"$to.city"

Opção 3

Outra opção seria uma quantidade de pedidos por localidade, com quantidade, valor e uma lista com os respectivos pedidos contendo os itens.

A aggregation teria o seguinte body:

{
  "resource" : "orders",
  "pipeline" : [
    {
        "$match" : { "created_at": {
            "$gte" : "2022-01-01T00:00:00.000Z",
            "$lte" : "2023-07-11T23:59:59.999Z"
            }
        }
    },
    {
        "$project":{
            "_id": 1,
            "created_at": 1,
            "amount.total": 1,
            "items": 1,
            "to": { "$arrayElemAt": [ "$shipping_lines.to", 0 ] }
        }
    },
    {
        "$group": {
            "_id": { 
                "state": "$to.province_code" ,
                "city":"$to.city",
                "month": {"$month": "$created_at"},
                "year": {"$year": "$created_at"}
            },
            "count": { "$sum": 1 },
            "amount_orders": { "$sum": "$amount.total" },
            "list_orders":{
                "$addToSet": {"id":"$_id", "items": "$items", "amount": "$amount.total"}
            }
        }
    }    
  ]
 }

Espero que ajude. Qualquer dúvida estamos a disposição. :raising_hand_man:t5:

1 curtida

@wisley era exatamente isso!
Muito obg pela ajuda.
Será bem útil para decisão de promoções de frete e modelos que temos personalizados.

Abs!

1 curtida