[TIL] 음식점 랭킹 출력 23.07.20

이상훈·2023년 7월 20일
0

[내일배움캠프]

목록 보기
46/68

주문 건수에 따른 음식점 랭킹 출력

countTotalOrders = async (storeId, daysAgo) => {
    const currentDate = new Date();
    const startDate = new Date();
    startDate.setDate(currentDate.getDate() - daysAgo);

    const orderCount = await Order.count({
      where: {
        store_id: storeId,
        order_status: 'delivered',
        create_at: {
          [Op.between]: [startDate, currentDate],
        },
      },
    });

    return orderCount;
  };
  • 주문수가 많은 순서로 랭킹을 집계하기 위해 계산 메소드를 만들어 줌
  • 기간(일별, 주간, 월간 주문수)을 설정하여 3가지의 랭킹을 계산
  • 배달이 완료된 주문만 집계하기 위해 order_status : "delivered"를 적용
getStoreRanking = async (daysAgo) => {
    try {
      const stores = await this.storeRepository.getStore();

      const ranking = await Promise.all(
        stores.map(async (store) => {
          const storeId = store.id;
          const orderCount = await this.orderRepository.countTotalOrders(storeId, daysAgo);

          return {
            storeId,
            storeName: store.store_name,
            storeImg: store.store_img,
            storeAddress: store.store_address,
            orderCount,
          };
        })
      );

      ranking.sort((a, b) => b.orderCount - a.orderCount);

      return ranking;
    } catch (err) {
      console.error(err);
      return { code: 500, errorMessage: '랭킹 출력에 실패하였습니다.' };
    }
  };

고객의 재주문율에 따른 음식점 랭킹 출력

 countTotalReorders = async (storeId) => {
    const orders = await Order.findAll({
      where: {
        store_id: storeId,
        order_status: 'delivered',
      },
      attributes: ['store_id', 'user_id'],
    });
    // set을 사용하여 user_id가 userIds에 존재하는지 확인
    // 없으면 추가해주고 있다면 reorderCount를 올려줌
    const userIds = new Set();
    let reorderCount = 0;

    for (const order of orders) {
      if (!userIds.has(order.user_id)) {
        userIds.add(order.user_id);
      } else {
        reorderCount++;
      }
    }
    const total = orders.length;
    const averageRate = total > 0 ? (reorderCount / total) * 100 : 0;

    return { reorderCount, averageRate };
  };
}

set()을 사용하여 userIds에 해당 유저의 주문 건이 없다면 user_id를 추가한 뒤, 재주문이 이뤄진 주문 건이 있다면 reorderCount를 올려주는 방법으로 메서드를 구현.
주문이 아예 없는 경우 null값으로 출력되어 삼항 연산자로 주문이 없는 경우엔 0을 출력하도록 함

 getReorderRanking = async () => {
    try {
      const stores = await this.storeRepository.getStore();

      const ranking = await Promise.all(
        stores.map(async (store) => {
          const storeId = store.id;
          const { reorderCount, averageRate } = await this.orderRepository.countTotalReorders(
            storeId
          );

          return {
            storeId,
            storeName: store.store_name,
            storeImg: store.store_img,
            storeAddress: store.store_address,
            reorderCount,
            averageRate,
          };
        })
      );

      ranking.sort((a, b) => b.reorderCount - a.reorderCount);

      return ranking;
    } catch (err) {
      console.error(err);
      return { code: 500, errorMessage: '랭킹 출력에 실패하였습니다.' };
    }
  };
}

출력결과

주문 건수 별 랭킹

{
  "ranking": [
    {
      "storeId": 4,
      "storeName": "랭크테스트2",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "orderCount": 3
    },
    {
      "storeId": 3,
      "storeName": "랭크테스트1",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "orderCount": 2
    },
    {
      "storeId": 2,
      "storeName": "성민네 참기름집",
      "storeImg": "https://1031a197-0276-42f1-a86d-9779681c058c.jpeg",
      "storeAddress": "우리집 강아지 복슬강아지",
      "orderCount": 1
    },
    {
      "storeId": 5,
      "storeName": "랭크테스트3",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "orderCount": 1
    },
  ]
}

재주문율이 높은 가게 랭킹

{
  "reorderRanking": [
    {
      "storeId": 2,
      "storeName": "성민네 참기름집",
      "storeImg": "https://1031a197-0276-42f1-a86d-9779681c058c.jpeg",
      "storeAddress": "우리집 강아지 복슬강아지",
      "reorderCount": 0,
      "averageRate": 0
    },
    {
      "storeId": 3,
      "storeName": "랭크테스트1",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "reorderCount": 0,
      "averageRate": 0
    },
    {
      "storeId": 5,
      "storeName": "랭크테스트3",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "reorderCount": 0,
      "averageRate": 0
    },
    {
      "storeId": 7,
      "storeName": "랭크테스트5",
      "storeImg": null,
      "storeAddress": "서울시 강남구",
      "reorderCount": 0,
      "averageRate": 0
    },
  ]
}

재주문율이 높은 가게의 경우 아직 데이터가 입력된게 없어 전부 0으로 출력되지만 추후 데이터 입력 후 확인예정

profile
코린이

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

아주 유용한 정보네요!

답글 달기