728x90
- 지피티 질문:
RankingTabScreen 의 카드를 보면 RankingCardWidget에서
블록으로
랭킹 탭 구현 과정 정리
1. 초기 요구사항
- 판매량(salesVolume)이 높은 상품이 위쪽에 배치되어야 함
- 카테고리별 필터링 기능 필요
- 상품 카드에는 상품 이미지, 이름, 가격, 할인율, 별점, 리뷰 수 표시
2. 구현 단계
2.1 BLoC 패턴 구현
// Events
abstract class RankingEvent {}
class LoadRankingProducts extends RankingEvent {
final String? categoryId; // optional - 전체 조회시는 null
LoadRankingProducts({this.categoryId});
}
// States
abstract class RankingState {}
class RankingInitial extends RankingState {}
class RankingLoading extends RankingState {}
class RankingLoaded extends RankingState {
final List<ProductModel> products;
RankingLoaded(this.products);
}
class RankingError extends RankingState {
final String message;
RankingError(this.message);
}
2.2 카테고리 매핑 설정
// 카테고리와 ID 매핑
final List<String> categoryFilters = [
'전체',
'스킨케어', // ID: '1'
'마스크팩', // ID: '2'
'클렌징', // ID: '3'
'선케어', // ID: '4'
'메이크업', // ID: '5'
'뷰티소품', // ID: '6'
'맨즈케어', // ID: '7'
'헤어케어', // ID: '8'
'바디케어' // ID: '9'
];
2.3 Repository 구현
초기에는 복합 쿼리를 시도했으나 Firestore 인덱스 에러 발생:
Future<List<ProductModel>> getRankingProducts(String? categoryId) async {
try {
Query query = _firestore.collection('products');
if (categoryId != null) {
// 1. 카테고리로 필터링
query = query.where('categoryId', isEqualTo: categoryId);
final QuerySnapshot snapshot = await query.get();
var products = snapshot.docs
.map((doc) {
Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
data['productId'] = doc.id;
return ProductModel.fromMap(data);
})
.toList();
// 2. 클라이언트에서 정렬
products.sort((a, b) => b.salesVolume.compareTo(a.salesVolume));
// 3. 상위 10개만 반환
return products.take(10).toList();
} else {
// 전체 상품 조회
return await _getTopProducts();
}
} catch (e) {
print('Error in getRankingProducts: $e');
throw Exception('랭킹 상품을 불러오는데 실패했습니다.');
}
}
2.4 데이터 처리 방식 비교
방법 1 (선택한 방법):
- 장점:
- 구현이 단순
- 한 번의 쿼리로 처리
- 추가 정렬/필터링이 필요할 때 유연함
- 단점:
- 카테고리의 상품이 많을 경우 모든 데이터를 가져와야 함
- 클라이언트에서 정렬하므로 메모리 사용량 증가
방법 2 (두 단계 쿼리):
- 장점:
- 메모리 사용이 더 효율적
- 대량의 데이터 처리에 적합
- 단점:
- 구현이 더 복잡
- 두 번의 쿼리로 인한 지연 가능성
2.5 복합 인덱스 설명
복합 인덱스는 여러 필드를 조합해서 빠른 검색을 가능하게 하는 데이터베이스 기능입니다.
// 단일 필드 쿼리 (인덱스 불필요)
query.where('categoryId', isEqualTo: '1')
// 복합 쿼리 (복합 인덱스 필요)
query.where('categoryId', isEqualTo: '1')
.orderBy('salesVolume', descending: true)
현재는 복합 인덱스 대신 방법 1을 선택하여:
- 먼저 카테고리로 필터링
- 앱에서 판매량 기준으로 정렬
- 상위 10개 선택
하는 방식으로 구현했습니다.
3. 최종 선택 및 권장사항
- 현재 단계: 방법 1 사용 (개발 초기에 적합)
- 확장 계획:
- 상품 수가 적을 때 (100개 이하/카테고리): 현재 방식 유지
- 상품 수가 많아질 때: 방법 2 또는 Firestore 인덱스로 마이그레이션
728x90
'♠♠기술 구현' 카테고리의 다른 글
좋아요 데이터베이스 연동 과정 (0) | 2024.11.08 |
---|---|
오늘의 특가 개발과정 (1) | 2024.11.06 |
SHA-1키 얻는법 (0) | 2024.11.05 |
모델쪽 구조 파악 (3) | 2024.11.04 |
파이어스토어에 데이터 올리기// 컬렉션 생성하는 과정 (0) | 2024.11.04 |