Giter Site home page Giter Site logo

delight-server's People

Contributors

changhwank avatar dohyung97022 avatar stat-kwon avatar

Stargazers

 avatar  avatar

delight-server's Issues

FOOD DB 구축

작업

  • 음식 카테고리 DB 입력

  • Food Data 입력

  • PS -
    음식 Category 추상화 레벨 이슈로 가장 큰 추상화 레벨로 Category 생성
    이미지는 네이버 음식백과를 기준으로 최대한 가져온다.

Spring AOP 를 이용한 Logging 적용

  • 추천시간 특정을 위한 타이머 적용
  • 장애 발생이 가능한 기능에 log를 적용해서 분석 할 수 있도록 한다.
  • 로그 적용과정을 문서화 하여 공유

DB v4 Migration 진행

  • Tag Table Add Column String TagType

  • User, Recommendation Table N:M 연관관계 설정

  • Recommendation Table count 컬럼 드랍

카테고리별 랭킹 Top10 기능개발

요구사항

  • 카테고리별 랭킹 Top10 조회기능을 만들어야 한다.
    조건 1 : 이때, CategoryId = 0일 경우 카테고리에 상관없는 전체 조회, CategoryId != 0일 경우 해당 카테고리별 조회
    조건 2 : 00시~12시까지는 전날에 대한 카테고리별 랭킹 Top10, 12시~24시는 당일에 대한 카테고리별 랭킹 Top10

작업완료

  • 4개 테이블의 연관관계를 갖는 QueryDSL구현
  • 조건1, 2에 맞는 로직을 추가
  • ResponseDto로 자동생성 되도록 설계
  • BooleanExpression을 통한 compile시 타입체크 추가

QueryDSL

@Override
    public List<RecommendationRankResponse> findAllTopTenByCategoryId(Long id) {

        JPAQuery<RecommendationRankResponse> query = queryFactory
                .select(Projections.constructor(RecommendationRankResponse.class,
                        foodRecommendation.recommendation.count,
                        foodRecommendation.food.name,
                        foodRecommendation.food.imgUrl,
                        foodRecommendation.food.category.id))
                .from(foodRecommendation)
                .innerJoin(foodRecommendation.recommendation, recommendation)
                .innerJoin(foodRecommendation.food, food)
                .innerJoin(food.category, category);

        BooleanBuilder booleanBuilder = new BooleanBuilder();

        /*
          현재시간이 오전인지 오후인지 판별
          오전 : 전날 추천받은 게시물 , 오후 : 당일 추천받은 게시물
         */
        whetherAmPm(booleanBuilder);

        /*
         CategoryId = 0 이면 전체 추천랭킹 게시물 조회
         CategoryId != 0 이면 해당 카테고리별 게시물 조회
         */
        whetherCategoryId(id, booleanBuilder);

        return query.where(booleanBuilder)
                .orderBy(countDesc())
                .limit(10)
                .fetch();
    }

    private void whetherAmPm(BooleanBuilder booleanBuilder) {

        LocalDateTime nowTime = LocalDateTime.now();
        LocalDateTime startAmToday = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endAmToday = LocalDateTime.now().toLocalDate().atStartOfDay().plusHours(12);
        LocalDateTime endPmToday = LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1);

        if (nowTime.isBefore(startAmToday) && nowTime.isAfter(endAmToday)) {
            booleanBuilder.and(foodRecommendation.recommendation.createdAt.goe(startAmToday)
                    .and(foodRecommendation.recommendation.createdAt.lt(startAmToday)));
        }
        if (nowTime.isEqual(endAmToday) && nowTime.isBefore(endAmToday)) {
            booleanBuilder.and(foodRecommendation.recommendation.createdAt.goe(endAmToday)
                    .and(foodRecommendation.recommendation.createdAt.lt(endPmToday)));
        }
    }

    private void whetherCategoryId(Long id, BooleanBuilder booleanBuilder) {
        if (id != null && id != 0) {
            booleanBuilder.and(categoryIdEq(id));
        }
    }

    private OrderSpecifier<Integer> countDesc() {
        return foodRecommendation.recommendation.count.desc();
    }

    private BooleanExpression categoryIdEq(Long id) {
        return id != null ? foodRecommendation.food.category.id.eq(id) : null;
    }

고려 사항

  1. 연관관계를 맺는 Join을 할때 OuterJoin, InnerJoin, FetchJoin에 대한 성능 판단
  2. Dto 반환에 있어 프로퍼티 접근, 필드 직접 접근, 생성자 사용 고려
  3. 동적쿼리 BooleanBuilder와 where 다중 파라미터 중 사용 고려
  4. queryDSL 장점인 complie시 타입체크 고려
  5. queryDSL은 from절의 서브쿼리 (inline view)가 적용되지않아 서브쿼리 미사용

플라스크 서버 통신을 위한 RestTemplate 구축

작업 예정

  • #53
  • 구축된 서버 Local 환경 테스트

ARC를 이용한 서버간 통신 성공 이미지

  • Client( Post 요청 ) -> Main server( Post 요청 ) -> Temp server (Flask 대체 예정) -> Main server -> Client

image

미흡점 도출

  • 외부 서버가 필요하기에 내부 테스트 코드의 어려움 발생 ( 금주 토요일 해결예정 )

Redis 캐싱 적용

자주 호출 되는 API에 캐싱을 적용한다.

Task

  • - Redis 적용
  • - 캐싱을 하는 이유 정리
  • - ranking data 에 캐싱 추가
  • - 음식 목로 조회에 캐싱 추가

DB Migration V9 ~ V10

  • Drop table Food_Recommendation
  • RECOMMENDATION Table Name 을 FOOD_ID로 변경하여 FOOD 와 RECOMMENDATION을 1:N 관계로 변경

Recommendation save 로직 변경

  • Recommendation table
  • 중복 허용
  • Count는 Query로 구현
  • UserId를 갖을 수 있도록 컬럼 추가
  • user table과 다대다 관계
  • UserRecommendation table 생성

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.