Spaces:
Sleeping
Sleeping
| // ============================================================================= | |
| // populate_ja_ko.js | |
| // | |
| // Purpose : Seed Japanese (*Ja) and Korean (*Ko) fields for: | |
| // hotel, room, promotions, advertisement, visa_articles | |
| // Run with : mongosh "<MONGODB_URI>/wanderlust" --quiet --file populate_ja_ko.js | |
| // or inside mongosh shell: load('scripts/populate_ja_ko.js') | |
| // | |
| // Idempotent: Skips documents that already have a non-null Ja/Ko field. | |
| // Strategy : Template-based (no external API) — same approach as populate_vi_remaining.js | |
| // ============================================================================= | |
| // --------------------------------------------------------------------------- | |
| // === JAPANESE LOOKUP TABLES === | |
| // --------------------------------------------------------------------------- | |
| const cityMapJa = { | |
| // Vietnam | |
| 'Hanoi': 'ハノイ', 'Ho Chi Minh City': 'ホーチミン市', 'Da Nang': 'ダナン', | |
| 'Hoi An': 'ホイアン', 'Nha Trang': 'ニャチャン', 'Phu Quoc': 'フーコック', | |
| 'Hue': 'フエ', 'Ha Long': 'ハロン', 'Da Lat': 'ダラット', | |
| 'Vung Tau': 'ブンタウ', 'Quy Nhon': 'クイニョン', 'Phan Thiet': 'パンティエット', | |
| 'Can Tho': 'カントー', 'Hai Phong': 'ハイフォン', 'Lao Cai': 'ラオカイ', | |
| 'Sapa': 'サパ', 'Ninh Binh': 'ニンビン', 'Mui Ne': 'ムイネー', | |
| 'HCMC': 'ホーチミン市', 'Saigon': 'サイゴン', 'Ho Chi Minh': 'ホーチミン市', | |
| // Asia | |
| 'Bangkok': 'バンコク', 'Phuket': 'プーケット', 'Chiang Mai': 'チェンマイ', | |
| 'Tokyo': '東京', 'Osaka': '大阪', 'Kyoto': '京都', 'Sapporo': '札幌', | |
| 'Seoul': 'ソウル', 'Busan': '釜山', 'Jeju': '済州', | |
| 'Singapore': 'シンガポール', 'Kuala Lumpur': 'クアラルンプール', 'Penang': 'ペナン', | |
| 'Bali': 'バリ', 'Jakarta': 'ジャカルタ', 'Yogyakarta': 'ジョグジャカルタ', | |
| 'Hong Kong': '香港', 'Taipei': '台北', 'Beijing': '北京', 'Shanghai': '上海', | |
| 'Siem Reap': 'シェムリアップ', 'Phnom Penh': 'プノンペン', | |
| 'Vientiane': 'ビエンチャン', 'Luang Prabang': 'ルアンパバーン', | |
| 'Yangon': 'ヤンゴン', 'Kathmandu': 'カトマンズ', 'Colombo': 'コロンボ', | |
| 'Maldives': 'モルディブ', 'Dubai': 'ドバイ', 'Doha': 'ドーハ', | |
| // Europe/Others | |
| 'Paris': 'パリ', 'London': 'ロンドン', 'Rome': 'ローマ', 'Barcelona': 'バルセロナ', | |
| 'Amsterdam': 'アムステルダム', 'Vienna': 'ウィーン', 'Prague': 'プラハ', | |
| 'Sydney': 'シドニー', 'Melbourne': 'メルボルン', 'New York': 'ニューヨーク', | |
| 'Los Angeles': 'ロサンゼルス', 'Las Vegas': 'ラスベガス' | |
| }; | |
| const hotelTypeJaMap = { | |
| 'HOTEL': 'ホテル', | |
| 'VILLA': 'ヴィラ', | |
| 'APARTMENT': 'アパートメント', | |
| 'RESORT': 'リゾート', | |
| 'HOSTEL': 'ホステル', | |
| 'MOTEL': 'モーテル', | |
| 'GUEST_HOUSE': 'ゲストハウス' | |
| }; | |
| const amenityJaMap = { | |
| 'Free WiFi': '無料WiFi', | |
| 'WiFi': 'WiFi', | |
| 'Swimming Pool': 'スイミングプール', | |
| 'Pool': 'プール', | |
| 'Breakfast': '朝食', | |
| 'Free Breakfast': '無料朝食', | |
| 'Parking': '駐車場', | |
| 'Free Parking': '無料駐車場', | |
| 'Gym': 'ジム', | |
| 'Fitness Center': 'フィットネスセンター', | |
| 'Restaurant': 'レストラン', | |
| 'Bar': 'バー', | |
| 'Spa': 'スパ', | |
| 'Air Conditioning': 'エアコン', | |
| 'Airport Shuttle': '空港送迎', | |
| 'Room Service': 'ルームサービス', | |
| '24-Hour Front Desk': '24時間フロント', | |
| 'Concierge': 'コンシェルジュ', | |
| 'Laundry': 'ランドリー', | |
| 'Laundry Service': 'ランドリーサービス', | |
| 'Meeting Room': '会議室', | |
| 'Business Center': 'ビジネスセンター', | |
| 'Kids Club': 'キッズクラブ', | |
| 'Beach Access': 'ビーチアクセス', | |
| 'Private Beach': 'プライベートビーチ', | |
| 'Hot Tub': '温浴設備', | |
| 'Jacuzzi': 'ジャグジー', | |
| 'Sauna': 'サウナ', | |
| 'Minibar': 'ミニバー', | |
| 'Safe': 'セーフティボックス', | |
| 'Balcony': 'バルコニー', | |
| 'Sea View': 'シービュー', | |
| 'Mountain View': 'マウンテンビュー', | |
| 'City View': 'シティビュー', | |
| 'Non-smoking': '禁煙', | |
| 'Pet Friendly': 'ペット可', | |
| 'Elevator': 'エレベーター', | |
| 'Electric Kettle': '電気ケトル', | |
| 'TV': 'テレビ', | |
| 'Cable TV': 'ケーブルTV' | |
| }; | |
| const roomTypeJaMap = { | |
| 'SINGLE': 'シングルルーム', | |
| 'DOUBLE': 'ダブルルーム', | |
| 'SUITE': 'スイートルーム', | |
| 'FAMILY': 'ファミリールーム' | |
| }; | |
| // --------------------------------------------------------------------------- | |
| // === KOREAN LOOKUP TABLES === | |
| // --------------------------------------------------------------------------- | |
| const cityMapKo = { | |
| // Vietnam | |
| 'Hanoi': '하노이', 'Ho Chi Minh City': '호치민시', 'Da Nang': '다낭', | |
| 'Hoi An': '호이안', 'Nha Trang': '나트랑', 'Phu Quoc': '푸꾸옥', | |
| 'Hue': '후에', 'Ha Long': '하롱', 'Da Lat': '달랏', | |
| 'Vung Tau': '붕따우', 'Quy Nhon': '꾸이년', 'Phan Thiet': '판티엣', | |
| 'Can Tho': '껀터', 'Hai Phong': '하이퐁', 'Lao Cai': '라오까이', | |
| 'Sapa': '사파', 'Ninh Binh': '닌빈', 'Mui Ne': '무이네', | |
| 'HCMC': '호치민시', 'Saigon': '사이공', 'Ho Chi Minh': '호치민시', | |
| // Asia | |
| 'Bangkok': '방콕', 'Phuket': '푸켓', 'Chiang Mai': '치앙마이', | |
| 'Tokyo': '도쿄', 'Osaka': '오사카', 'Kyoto': '교토', 'Sapporo': '삿포로', | |
| 'Seoul': '서울', 'Busan': '부산', 'Jeju': '제주', | |
| 'Singapore': '싱가포르', 'Kuala Lumpur': '쿠알라룸푸르', 'Penang': '페낭', | |
| 'Bali': '발리', 'Jakarta': '자카르타', 'Yogyakarta': '족자카르타', | |
| 'Hong Kong': '홍콩', 'Taipei': '타이베이', 'Beijing': '베이징', 'Shanghai': '상하이', | |
| 'Siem Reap': '씨엠립', 'Phnom Penh': '프놈펜', | |
| 'Vientiane': '비엔티안', 'Luang Prabang': '루앙프라방', | |
| 'Yangon': '양곤', 'Kathmandu': '카트만두', 'Colombo': '콜롬보', | |
| 'Maldives': '몰디브', 'Dubai': '두바이', 'Doha': '도하', | |
| // Europe/Others | |
| 'Paris': '파리', 'London': '런던', 'Rome': '로마', 'Barcelona': '바르셀로나', | |
| 'Amsterdam': '암스테르담', 'Vienna': '빈', 'Prague': '프라하', | |
| 'Sydney': '시드니', 'Melbourne': '멜버른', 'New York': '뉴욕', | |
| 'Los Angeles': '로스앤젤레스', 'Las Vegas': '라스베이거스' | |
| }; | |
| const hotelTypeKoMap = { | |
| 'HOTEL': '호텔', | |
| 'VILLA': '빌라', | |
| 'APARTMENT': '아파트먼트', | |
| 'RESORT': '리조트', | |
| 'HOSTEL': '호스텔', | |
| 'MOTEL': '모텔', | |
| 'GUEST_HOUSE': '게스트하우스' | |
| }; | |
| const amenityKoMap = { | |
| 'Free WiFi': '무료 WiFi', | |
| 'WiFi': 'WiFi', | |
| 'Swimming Pool': '수영장', | |
| 'Pool': '수영장', | |
| 'Breakfast': '아침식사', | |
| 'Free Breakfast': '무료 아침식사', | |
| 'Parking': '주차장', | |
| 'Free Parking': '무료 주차장', | |
| 'Gym': '헬스장', | |
| 'Fitness Center': '피트니스 센터', | |
| 'Restaurant': '레스토랑', | |
| 'Bar': '바', | |
| 'Spa': '스파', | |
| 'Air Conditioning': '에어컨', | |
| 'Airport Shuttle': '공항 셔틀', | |
| 'Room Service': '룸서비스', | |
| '24-Hour Front Desk': '24시간 프론트', | |
| 'Concierge': '컨시어지', | |
| 'Laundry': '세탁 서비스', | |
| 'Laundry Service': '세탁 서비스', | |
| 'Meeting Room': '회의실', | |
| 'Business Center': '비즈니스 센터', | |
| 'Kids Club': '키즈 클럽', | |
| 'Beach Access': '해변 접근', | |
| 'Private Beach': '전용 해변', | |
| 'Hot Tub': '온수 욕조', | |
| 'Jacuzzi': '자쿠지', | |
| 'Sauna': '사우나', | |
| 'Minibar': '미니바', | |
| 'Safe': '금고', | |
| 'Balcony': '발코니', | |
| 'Sea View': '바다 전망', | |
| 'Mountain View': '산 전망', | |
| 'City View': '도시 전망', | |
| 'Non-smoking': '금연', | |
| 'Pet Friendly': '반려동물 동반 가능', | |
| 'Elevator': '엘리베이터', | |
| 'Electric Kettle': '전기 주전자', | |
| 'TV': 'TV', | |
| 'Cable TV': '케이블 TV' | |
| }; | |
| const roomTypeKoMap = { | |
| 'SINGLE': '싱글룸', | |
| 'DOUBLE': '더블룸', | |
| 'SUITE': '스위트룸', | |
| 'FAMILY': '패밀리룸' | |
| }; | |
| // --------------------------------------------------------------------------- | |
| // === HELPER FUNCTIONS — JAPANESE === | |
| // --------------------------------------------------------------------------- | |
| function translateAmenitiesJa(amenities, count) { | |
| if (!amenities || amenities.length === 0) return []; | |
| const result = []; | |
| for (let i = 0; i < Math.min(count, amenities.length); i++) { | |
| result.push(amenityJaMap[amenities[i]] || amenities[i]); | |
| } | |
| return result; | |
| } | |
| function buildHotelNameJa(hotel) { | |
| const typeLabel = hotelTypeJaMap[hotel.hotelType] || 'ホテル'; | |
| const cityJa = cityMapJa[hotel.city] || hotel.city || ''; | |
| const name = (hotel.name || '') | |
| .replace(/^(Hotel|Resort|Villa|Hostel|Apartment|Guesthouse|Guest House|Motel)\s+/i, '') | |
| .trim(); | |
| if (name) { | |
| return name + ' ' + typeLabel + (cityJa ? '(' + cityJa + ')' : ''); | |
| } | |
| return typeLabel + (cityJa ? '(' + cityJa + ')' : ''); | |
| } | |
| function buildAddressJa(hotel) { | |
| if (!hotel.address) return ''; | |
| let addr = hotel.address; | |
| for (const [en, ja] of Object.entries(cityMapJa)) { | |
| addr = addr.replace(new RegExp('\\b' + en + '\\b', 'gi'), ja); | |
| } | |
| addr = addr.replace(/\bStreet\b/gi, '通り'); | |
| addr = addr.replace(/\bAvenue\b/gi, '大通り'); | |
| addr = addr.replace(/\bDistrict\b/gi, '地区'); | |
| addr = addr.replace(/\bWard\b/gi, '区'); | |
| return addr; | |
| } | |
| function buildShortDescJa(hotel) { | |
| const typeLabel = hotelTypeJaMap[hotel.hotelType] || 'ホテル'; | |
| const stars = hotel.starRating || ''; | |
| const cityJa = cityMapJa[hotel.city] || hotel.city || ''; | |
| const ams = translateAmenitiesJa(hotel.amenities, 3); | |
| const amStr = ams.length > 0 ? '。' + ams.join('、') + 'を完備。' : '。'; | |
| const starPart = stars ? stars + 'つ星の' : ''; | |
| return cityJa + 'の' + starPart + typeLabel + amStr; | |
| } | |
| function buildDescJa(hotel) { | |
| const typeLabel = hotelTypeJaMap[hotel.hotelType] || 'ホテル'; | |
| const stars = hotel.starRating || ''; | |
| const cityJa = cityMapJa[hotel.city] || hotel.city || ''; | |
| const name = hotel.name || typeLabel; | |
| const ams = translateAmenitiesJa(hotel.amenities, 4); | |
| const starPart = stars ? stars + 'つ星の' : ''; | |
| let s1 = name + 'へようこそ。' + cityJa + 'に位置する' + starPart + typeLabel + 'です。'; | |
| let s2 = ams.length > 0 | |
| ? '当施設では' + ams.join('、') + 'などの設備をご利用いただけます。' | |
| : '快適なご滞在のために高品質なサービスをご提供しています。'; | |
| let s3 = 'ご家族でのご旅行、ビジネス出張のどちらにも最適です。'; | |
| return s1 + s2 + s3; | |
| } | |
| // --------------------------------------------------------------------------- | |
| // === HELPER FUNCTIONS — KOREAN === | |
| // --------------------------------------------------------------------------- | |
| function translateAmenitiesKo(amenities, count) { | |
| if (!amenities || amenities.length === 0) return []; | |
| const result = []; | |
| for (let i = 0; i < Math.min(count, amenities.length); i++) { | |
| result.push(amenityKoMap[amenities[i]] || amenities[i]); | |
| } | |
| return result; | |
| } | |
| function buildHotelNameKo(hotel) { | |
| const typeLabel = hotelTypeKoMap[hotel.hotelType] || '호텔'; | |
| const cityKo = cityMapKo[hotel.city] || hotel.city || ''; | |
| const name = (hotel.name || '') | |
| .replace(/^(Hotel|Resort|Villa|Hostel|Apartment|Guesthouse|Guest House|Motel)\s+/i, '') | |
| .trim(); | |
| if (name) { | |
| return name + ' ' + typeLabel + (cityKo ? ', ' + cityKo : ''); | |
| } | |
| return typeLabel + (cityKo ? ', ' + cityKo : ''); | |
| } | |
| function buildAddressKo(hotel) { | |
| if (!hotel.address) return ''; | |
| let addr = hotel.address; | |
| for (const [en, ko] of Object.entries(cityMapKo)) { | |
| addr = addr.replace(new RegExp('\\b' + en + '\\b', 'gi'), ko); | |
| } | |
| addr = addr.replace(/\bStreet\b/gi, '거리'); | |
| addr = addr.replace(/\bAvenue\b/gi, '대로'); | |
| addr = addr.replace(/\bDistrict\b/gi, '구'); | |
| addr = addr.replace(/\bWard\b/gi, '동'); | |
| return addr; | |
| } | |
| function buildShortDescKo(hotel) { | |
| const typeLabel = hotelTypeKoMap[hotel.hotelType] || '호텔'; | |
| const stars = hotel.starRating || ''; | |
| const cityKo = cityMapKo[hotel.city] || hotel.city || ''; | |
| const ams = translateAmenitiesKo(hotel.amenities, 3); | |
| const amStr = ams.length > 0 ? ', ' + ams.join(', ') + ' 완비' : ''; | |
| const starPart = stars ? stars + '성급 ' : ''; | |
| return cityKo + ' 소재 ' + starPart + typeLabel + amStr + '.'; | |
| } | |
| function buildDescKo(hotel) { | |
| const typeLabel = hotelTypeKoMap[hotel.hotelType] || '호텔'; | |
| const stars = hotel.starRating || ''; | |
| const cityKo = cityMapKo[hotel.city] || hotel.city || ''; | |
| const name = hotel.name || typeLabel; | |
| const ams = translateAmenitiesKo(hotel.amenities, 4); | |
| const starPart = stars ? stars + '성급 ' : ''; | |
| let s1 = name + '에 오신 것을 환영합니다. ' + cityKo + '에 위치한 ' + starPart + typeLabel + '입니다.'; | |
| let s2 = ams.length > 0 | |
| ? '본 시설은 ' + ams.join(', ') + ' 등의 편의시설을 갖추고 있습니다.' | |
| : '고품질 서비스로 편안한 숙박을 제공합니다.'; | |
| let s3 = '가족 여행 및 비즈니스 출장 모두에 적합한 최상의 선택입니다.'; | |
| return s1 + ' ' + s2 + ' ' + s3; | |
| } | |
| // --------------------------------------------------------------------------- | |
| // === SECTION 1 — hotel === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== [1/5] Updating hotel collection (Ja + Ko) ==='); | |
| let hotelUpdated = 0; | |
| db.hotel.find({}).forEach(function(hotel) { | |
| const setFields = {}; | |
| // Japanese | |
| if (!hotel.nameJa) setFields.nameJa = buildHotelNameJa(hotel); | |
| if (!hotel.addressJa) setFields.addressJa = buildAddressJa(hotel); | |
| if (!hotel.shortDescriptionJa) setFields.shortDescriptionJa = buildShortDescJa(hotel); | |
| if (!hotel.descriptionJa) setFields.descriptionJa = buildDescJa(hotel); | |
| // Korean | |
| if (!hotel.nameKo) setFields.nameKo = buildHotelNameKo(hotel); | |
| if (!hotel.addressKo) setFields.addressKo = buildAddressKo(hotel); | |
| if (!hotel.shortDescriptionKo) setFields.shortDescriptionKo = buildShortDescKo(hotel); | |
| if (!hotel.descriptionKo) setFields.descriptionKo = buildDescKo(hotel); | |
| if (Object.keys(setFields).length > 0) { | |
| db.hotel.updateOne({ _id: hotel._id }, { $set: setFields }); | |
| hotelUpdated++; | |
| } | |
| }); | |
| print(' Updated ' + hotelUpdated + ' hotels with Ja/Ko fields'); | |
| // --------------------------------------------------------------------------- | |
| // === SECTION 2 — room === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== [2/5] Updating room collection (Ja + Ko) ==='); | |
| let roomUpdated = 0; | |
| db.room.find({}).forEach(function(room) { | |
| const setFields = {}; | |
| if (!room.nameJa) { | |
| setFields.nameJa = roomTypeJaMap[room.type] || room.type || '客室'; | |
| } | |
| if (!room.descriptionJa) { | |
| const typeJa = roomTypeJaMap[room.type] || '客室'; | |
| const area = room.size ? '。広さ' + room.size + '㎡' : ''; | |
| const bed = room.bedType ? '、' + room.bedType : ''; | |
| const guests = room.maxOccupancy ? '、最大' + room.maxOccupancy + '名様' : ''; | |
| setFields.descriptionJa = typeJa + area + bed + guests + '。'; | |
| } | |
| if (!room.nameKo) { | |
| setFields.nameKo = roomTypeKoMap[room.type] || room.type || '객실'; | |
| } | |
| if (!room.descriptionKo) { | |
| const typeKo = roomTypeKoMap[room.type] || '객실'; | |
| const area = room.size ? ', 면적 ' + room.size + '㎡' : ''; | |
| const bed = room.bedType ? ', ' + room.bedType : ''; | |
| const guests = room.maxOccupancy ? ', 최대 ' + room.maxOccupancy + '명' : ''; | |
| setFields.descriptionKo = typeKo + area + bed + guests + '.'; | |
| } | |
| if (Object.keys(setFields).length > 0) { | |
| db.room.updateOne({ _id: room._id }, { $set: setFields }); | |
| roomUpdated++; | |
| } | |
| }); | |
| print(' Updated ' + roomUpdated + ' rooms with Ja/Ko fields'); | |
| // --------------------------------------------------------------------------- | |
| // === SECTION 3 — promotions === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== [3/5] Updating promotions collection (Ja + Ko) ==='); | |
| const promoCategoryJaMap = { | |
| 'HOTEL': 'ホテル', 'FLIGHT': 'フライト', | |
| 'CAR': 'レンタカー', 'ACTIVITY': 'アクティビティ', 'ALL': '全サービス' | |
| }; | |
| const promoCategoryKoMap = { | |
| 'HOTEL': '호텔', 'FLIGHT': '항공편', | |
| 'CAR': '렌터카', 'ACTIVITY': '액티비티', 'ALL': '전체 서비스' | |
| }; | |
| let promoUpdated = 0; | |
| db.promotions.find({}).forEach(function(promo) { | |
| const setFields = {}; | |
| const catJa = promo.category ? (promoCategoryJaMap[promo.category] || promo.category) : 'サービス'; | |
| const catKo = promo.category ? (promoCategoryKoMap[promo.category] || promo.category) : '서비스'; | |
| if (!promo.titleJa) { | |
| if (promo.type === 'PERCENTAGE' && promo.value) | |
| setFields.titleJa = catJa + ' ' + promo.value + '%割引'; | |
| else if (promo.type === 'FIXED_AMOUNT' && promo.value) | |
| setFields.titleJa = catJa + ' ' + Number(promo.value).toLocaleString() + '円割引'; | |
| else | |
| setFields.titleJa = (promo.code ? 'コード ' + promo.code + ' の' : '') + catJa + '特別割引'; | |
| } | |
| if (!promo.descriptionJa) { | |
| const parts = []; | |
| if (promo.type === 'PERCENTAGE' && promo.value) | |
| parts.push(catJa + 'が今すぐ' + promo.value + '%オフ。'); | |
| else if (promo.type === 'FIXED_AMOUNT' && promo.value) | |
| parts.push(catJa + 'のご予約で' + Number(promo.value).toLocaleString() + '円割引。'); | |
| else | |
| parts.push(catJa + 'のお得なキャンペーン。'); | |
| if (promo.minSpend) parts.push('最低注文金額:' + Number(promo.minSpend).toLocaleString() + '円。'); | |
| if (promo.endDate) parts.push('有効期限:' + promo.endDate + '。'); | |
| setFields.descriptionJa = parts.join(''); | |
| } | |
| if (!promo.titleKo) { | |
| if (promo.type === 'PERCENTAGE' && promo.value) | |
| setFields.titleKo = catKo + ' ' + promo.value + '% 할인'; | |
| else if (promo.type === 'FIXED_AMOUNT' && promo.value) | |
| setFields.titleKo = catKo + ' ' + Number(promo.value).toLocaleString() + '원 할인'; | |
| else | |
| setFields.titleKo = (promo.code ? '코드 ' + promo.code + ' - ' : '') + catKo + ' 특별 할인'; | |
| } | |
| if (!promo.descriptionKo) { | |
| const parts = []; | |
| if (promo.type === 'PERCENTAGE' && promo.value) | |
| parts.push(catKo + ' 지금 바로 ' + promo.value + '% 할인.'); | |
| else if (promo.type === 'FIXED_AMOUNT' && promo.value) | |
| parts.push(catKo + ' 예약 시 ' + Number(promo.value).toLocaleString() + '원 할인.'); | |
| else | |
| parts.push(catKo + ' 특별 프로모션.'); | |
| if (promo.minSpend) parts.push('최소 주문 금액: ' + Number(promo.minSpend).toLocaleString() + '원.'); | |
| if (promo.endDate) parts.push('유효기간: ' + promo.endDate + '.'); | |
| setFields.descriptionKo = parts.join(' '); | |
| } | |
| if (Object.keys(setFields).length > 0) { | |
| db.promotions.updateOne({ _id: promo._id }, { $set: setFields }); | |
| promoUpdated++; | |
| } | |
| }); | |
| print(' Updated ' + promoUpdated + ' promotions with Ja/Ko fields'); | |
| // --------------------------------------------------------------------------- | |
| // === SECTION 4 — advertisement === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== [4/5] Updating advertisement collection (Ja + Ko) ==='); | |
| const adKeywordJaMap = [ | |
| ['Summer Sale', '夏のセール'], ['Flash Sale', 'フラッシュセール'], | |
| ['New Destinations', '新目的地'], ['Special Offer', '特別オファー'], | |
| ['Exclusive Deal', '限定ディール'], ['Weekend Deal', '週末ディール'], | |
| ['Holiday Sale', '休暇セール'], ['Early Bird', '早期割引'], | |
| ['Last Minute', '直前割引'], ['Best Price', '最安値'], | |
| ['Top Hotels', 'おすすめホテル'], ['Luxury Hotels', '高級ホテル'], | |
| ['Budget Hotels', 'リーズナブルなホテル'], ['Beach Resorts', 'ビーチリゾート'], | |
| ['City Break', '都市旅行'], ['Family Travel', 'ファミリー旅行'], | |
| ['Honeymoon', 'ハネムーン'], ['Car Rental', 'レンタカー'], | |
| ['Flight Deals', 'フライト割引'], ['Hotel Deals', 'ホテル割引'], | |
| ['Tour Packages', 'ツアーパッケージ'] | |
| ]; | |
| const adKeywordKoMap = [ | |
| ['Summer Sale', '여름 세일'], ['Flash Sale', '플래시 세일'], | |
| ['New Destinations', '새로운 여행지'], ['Special Offer', '특별 혜택'], | |
| ['Exclusive Deal', '독점 딜'], ['Weekend Deal', '주말 딜'], | |
| ['Holiday Sale', '휴가 세일'], ['Early Bird', '조기 예약 할인'], | |
| ['Last Minute', '막판 할인'], ['Best Price', '최저가'], | |
| ['Top Hotels', '추천 호텔'], ['Luxury Hotels', '럭셔리 호텔'], | |
| ['Budget Hotels', '합리적인 호텔'], ['Beach Resorts', '비치 리조트'], | |
| ['City Break', '도시 여행'], ['Family Travel', '가족 여행'], | |
| ['Honeymoon', '허니문'], ['Car Rental', '렌터카'], | |
| ['Flight Deals', '항공편 할인'], ['Hotel Deals', '호텔 할인'], | |
| ['Tour Packages', '투어 패키지'] | |
| ]; | |
| function translateAdJa(text) { | |
| if (!text) return ''; | |
| for (const [en, ja] of adKeywordJaMap) { | |
| if (text.toLowerCase().includes(en.toLowerCase())) | |
| return text.replace(new RegExp(en, 'gi'), ja); | |
| } | |
| return text; | |
| } | |
| function translateAdKo(text) { | |
| if (!text) return ''; | |
| for (const [en, ko] of adKeywordKoMap) { | |
| if (text.toLowerCase().includes(en.toLowerCase())) | |
| return text.replace(new RegExp(en, 'gi'), ko); | |
| } | |
| return text; | |
| } | |
| let adUpdated = 0; | |
| db.advertisement.find({}).forEach(function(ad) { | |
| const setFields = {}; | |
| if (!ad.titleJa) setFields.titleJa = translateAdJa(ad.title) || (ad.title || ''); | |
| if (!ad.descriptionJa) setFields.descriptionJa = translateAdJa(ad.description) || (ad.description || ''); | |
| if (!ad.titleKo) setFields.titleKo = translateAdKo(ad.title) || (ad.title || ''); | |
| if (!ad.descriptionKo) setFields.descriptionKo = translateAdKo(ad.description) || (ad.description || ''); | |
| if (Object.keys(setFields).length > 0) { | |
| db.advertisement.updateOne({ _id: ad._id }, { $set: setFields }); | |
| adUpdated++; | |
| } | |
| }); | |
| print(' Updated ' + adUpdated + ' advertisements with Ja/Ko fields'); | |
| // --------------------------------------------------------------------------- | |
| // === SECTION 5 — visa_articles === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== [5/5] Updating visa_articles collection (Ja + Ko) ==='); | |
| const countryJaMap = { | |
| 'United States': 'アメリカ', 'USA': 'アメリカ', 'US': 'アメリカ', | |
| 'United Kingdom': 'イギリス', 'UK': 'イギリス', | |
| 'Japan': '日本', 'South Korea': '韓国', 'Korea': '韓国', | |
| 'China': '中国', 'Australia': 'オーストラリア', 'Canada': 'カナダ', | |
| 'Germany': 'ドイツ', 'France': 'フランス', 'Singapore': 'シンガポール', | |
| 'Thailand': 'タイ', 'Malaysia': 'マレーシア', 'Indonesia': 'インドネシア', | |
| 'Vietnam': 'ベトナム', 'Taiwan': '台湾', 'Hong Kong': '香港', | |
| 'India': 'インド', 'Turkey': 'トルコ', 'Italy': 'イタリア', | |
| 'Spain': 'スペイン', 'Maldives': 'モルディブ', 'Dubai': 'ドバイ' | |
| }; | |
| const countryKoMap = { | |
| 'United States': '미국', 'USA': '미국', 'US': '미국', | |
| 'United Kingdom': '영국', 'UK': '영국', | |
| 'Japan': '일본', 'South Korea': '한국', 'Korea': '한국', | |
| 'China': '중국', 'Australia': '호주', 'Canada': '캐나다', | |
| 'Germany': '독일', 'France': '프랑스', 'Singapore': '싱가포르', | |
| 'Thailand': '태국', 'Malaysia': '말레이시아', 'Indonesia': '인도네시아', | |
| 'Vietnam': '베트남', 'Taiwan': '대만', 'Hong Kong': '홍콩', | |
| 'India': '인도', 'Turkey': '터키', 'Italy': '이탈리아', | |
| 'Spain': '스페인', 'Maldives': '몰디브', 'Dubai': '두바이' | |
| }; | |
| const visaCategoryJaMap = { | |
| 'tourist': '観光', 'business': 'ビジネス', 'student': '留学', | |
| 'work': '就労', 'transit': '通過', 'e-visa': '電子ビザ', | |
| 'evisa': '電子ビザ', 'on arrival': '到着時ビザ', 'visa-free': 'ビザ免除' | |
| }; | |
| const visaCategoryKoMap = { | |
| 'tourist': '관광', 'business': '비즈니스', 'student': '유학', | |
| 'work': '취업', 'transit': '경유', 'e-visa': '전자비자', | |
| 'evisa': '전자비자', 'on arrival': '도착비자', 'visa-free': '무비자' | |
| }; | |
| function buildVisaTitleJa(article) { | |
| const countryJa = countryJaMap[article.country] || article.country || ''; | |
| const catJa = article.category ? (visaCategoryJaMap[article.category.toLowerCase()] || '') : ''; | |
| if (countryJa) return countryJa + (catJa ? 'の' + catJa : '') + 'ビザガイド'; | |
| return (article.title || '') + '(日本語)'; | |
| } | |
| function buildVisaExcerptJa(article) { | |
| const countryJa = countryJaMap[article.country] || article.country || ''; | |
| const catJa = article.category ? (visaCategoryJaMap[article.category.toLowerCase()] || '') : ''; | |
| if (countryJa) { | |
| const parts = [countryJa + 'への' + (catJa ? catJa : '') + 'ビザ申請の完全ガイドです。']; | |
| if (article.processingTime) parts.push('処理時間:' + article.processingTime + '。'); | |
| if (article.fee) parts.push('申請料:' + article.fee + 'USD。'); | |
| return parts.join(''); | |
| } | |
| return article.excerpt || ''; | |
| } | |
| function buildVisaTitleKo(article) { | |
| const countryKo = countryKoMap[article.country] || article.country || ''; | |
| const catKo = article.category ? (visaCategoryKoMap[article.category.toLowerCase()] || '') : ''; | |
| if (countryKo) return countryKo + (catKo ? ' ' + catKo : '') + ' 비자 가이드'; | |
| return (article.title || '') + ' (한국어)'; | |
| } | |
| function buildVisaExcerptKo(article) { | |
| const countryKo = countryKoMap[article.country] || article.country || ''; | |
| const catKo = article.category ? (visaCategoryKoMap[article.category.toLowerCase()] || '') : ''; | |
| if (countryKo) { | |
| const parts = [countryKo + (catKo ? ' ' + catKo : '') + ' 비자 신청 완전 가이드입니다.']; | |
| if (article.processingTime) parts.push('처리 기간: ' + article.processingTime + '.'); | |
| if (article.fee) parts.push('신청 수수료: ' + article.fee + 'USD.'); | |
| return parts.join(' '); | |
| } | |
| return article.excerpt || ''; | |
| } | |
| let visaUpdated = 0; | |
| db.visa_articles.find({}).forEach(function(article) { | |
| const setFields = {}; | |
| if (!article.titleJa) setFields.titleJa = buildVisaTitleJa(article) || article.title || ''; | |
| if (!article.excerptJa) setFields.excerptJa = buildVisaExcerptJa(article) || article.excerpt || ''; | |
| if (!article.titleKo) setFields.titleKo = buildVisaTitleKo(article) || article.title || ''; | |
| if (!article.excerptKo) setFields.excerptKo = buildVisaExcerptKo(article) || article.excerpt || ''; | |
| if (Object.keys(setFields).length > 0) { | |
| db.visa_articles.updateOne({ _id: article._id }, { $set: setFields }); | |
| visaUpdated++; | |
| } | |
| }); | |
| print(' Updated ' + visaUpdated + ' visa articles with Ja/Ko fields'); | |
| // --------------------------------------------------------------------------- | |
| // === VERIFICATION === | |
| // --------------------------------------------------------------------------- | |
| print(''); | |
| print('=== Verification: sample documents ==='); | |
| const sampleHotel = db.hotel.findOne({}, { name: 1, nameJa: 1, nameKo: 1, addressJa: 1, addressKo: 1 }); | |
| if (sampleHotel) { | |
| print('Sample Hotel:'); | |
| print(' name: ' + sampleHotel.name); | |
| print(' nameJa: ' + sampleHotel.nameJa); | |
| print(' nameKo: ' + sampleHotel.nameKo); | |
| print(' addressJa: ' + sampleHotel.addressJa); | |
| print(' addressKo: ' + sampleHotel.addressKo); | |
| } | |
| const sampleRoom = db.room.findOne({}, { name: 1, nameJa: 1, nameKo: 1 }); | |
| if (sampleRoom) { | |
| print('Sample Room:'); | |
| print(' name: ' + sampleRoom.name); | |
| print(' nameJa: ' + sampleRoom.nameJa); | |
| print(' nameKo: ' + sampleRoom.nameKo); | |
| } | |
| print(''); | |
| print('Done! All Ja/Ko fields populated.'); | |