프롤로그
이 문서에서는 Couchbase로의 일회성 MongoDB 마이그레이션에 대해 안내합니다. MongoDB 데이터 구조에서 내보내고, Couchbase로 가져오고, 해당 문서에서 몇 가지 기본적인 변환을 수행하는 방법을 배우게 됩니다.
이 블로그의 모든 코드는 다음 Git 리포지토리에서 사용할 수 있습니다: 몽고DB-카우치베이스
전제 조건
이 문서에서는 MongoDB 클러스터에 로드된 샘플 mflix 데이터 세트를 사용합니다. 저는 MongoDB Atlas를 사용하고 있지만 이 문서의 정보는 Atlas가 아닌 MongoDB 설치에도 적용됩니다. 샘플 데이터 세트를 MongoDB에 로드해야 하는 경우에는 여기 지침.
몽고DB 컴퍼스 는 데이터 세트를 내보내는 데 사용되며, 이 문서에서는 샘플 mflix 데이터 세트가 있는 MongoDB 클러스터에 연결하도록 이미 구성되어 있다고 가정합니다.
또한 데이터, 인덱스, 쿼리 및 이벤트 서비스가 활성화된 Couchbase Server Enterprise Edition(EE) 6.5 클러스터가 필요합니다(참고: 인덱스 및 쿼리는 추후 문서에서 사용됨). 저는 단일 노드 로컬 설치의 Couchbase Sever EE를 사용하고 있지만, 이 문서의 정보는 모든 Couchbase Server EE 클러스터에 적용됩니다.
기존 Couchbase Server EE 클러스터가 없는 경우 다음 링크를 통해 빠르게 시작하고 실행할 수 있습니다:
- Couchbase Sever EE 6.5 다운로드
- 카우치베이스 서버 EE 설치
- 단일 노드 클러스터 프로비저닝 (참고: 클러스터 구성에 기본값을 사용하세요.)
JSON, BSON 및 확장 JSON
MongoDB와 Couchbase는 모두 문서 데이터베이스이며 둘 다 JSON 문서를 저장합니다. 그러나 MongoDB는 BSON이라는 바이너리 인코딩 형식으로 JSON 문서를 표현합니다. JSON은 BSON에서 지원하는 유형의 하위 집합만 나타낼 수 있습니다. 유형 정보를 보존하기 위해 MongoDB는 JSON 형식에 대한 확장을 포함하는 확장 JSON을 사용합니다. 이 형식은 MongoDB 확장 JSON 사양 에서 다양한 확장 JSON 유형 및 규칙에 대한 자세한 내용을 확인하세요.
다음은 몽고DB가 다양한 유형의 정보를 어떻게 표현하는지에 대한 몇 가지 예시입니다:
- ObjectId: “_id”:{“$oid”:”573a1390f29313caabcd4135″}
- 정수: "runtime":{"$numberInt":"1″}
- 날짜: “released”:{“$date”:{“$numberLong”:”-2418768000000″}}
- 더블: "rating":{"$numberDouble":"6.2″}
Couchbase는 이 정보를 저장할 수 있지만, 확장 JSON 형식을 사용하지 않는 문서로 작업하는 것이 더 쉽습니다. 위의 예시를 사용하면 값은 다음과 같이 표시됩니다:
- ObjectId: “_id”:”573a1390f29313caabcd4135″
- 정수: "런타임":1
- 날짜: “released”:-2418768000000
- 더블: "rating":6.2
MongoDB에서 데이터 내보내기
몽고DB 컴파스를 사용하여 내보내기 영화 그리고 댓글 컬렉션의 sample_mflix 데이터베이스에 저장합니다. Compass에서 sample_mflix 데이터베이스 항목을 클릭한 다음 댓글.
를 선택하고 컬렉션 -> 컬렉션 내보내기 메뉴 항목을 선택합니다. 선택 전체 컬렉션 내보내기 를 클릭하고 필드 선택.
모든 필드를 선택하고 출력 선택.
선택 JSON 내보내기 파일 유형을 선택하고 출력 파일을 지정한 다음 내보내기.
에도 동일한 작업을 수행합니다. 영화 컬렉션.
카우치베이스로 데이터 가져오기
다음으로, MongoDB 수집 데이터를 Couchbase로 가져옵니다. 위에서 언급했듯이 내보낸 데이터는 확장 JSON 형식이므로 Couchbase 이벤트 서비스 는 문서를 Couchbase로 가져올 때 실시간으로 데이터에 약간의 변환을 수행하는 데 사용됩니다.
크게 보면 다음과 같은 흐름이 있습니다:
- 사용 cbimport 유틸리티 를 사용하여 JSON 문서를 수신 버킷.
- 문서가 작성되면 수신 버킷을 사용하면 이벤트 함수가 문서를 변환합니다.
- 변환이 성공하면 변환된 문서가 다음과 같이 sample_mflix 버킷.
- 오류가 있는 경우 원본 문서가 다음과 같이 작성됩니다. 오류 버킷에 추가합니다. 문서의 오류 속성에는 오류 메시지가 포함됩니다.
버킷 만들기
위에서 언급한 세 개의 버킷을 만듭니다. 버킷을 만들려면 버킷 생성에 대한 문서 를 참조하여 다양한 설정과 값 설정 시 고려 사항에 대한 자세한 내용을 확인하세요.
그리고 수신 버킷은 Couchbase로 문서를 가져올 때 문서를 임시로 저장합니다. 이것은 임시 버킷 를 사용하면 이러한 문서에 대한 영구 저장소가 필요하지 않습니다. 이벤트 함수는 이를 변환하여 sample_mflix 또는 오류 버킷에 기록합니다.
문서가 변환된 후에도 버킷에 남아 있을 필요가 없으므로 버킷은 다음과 같이 구성됩니다. 타임 투 리브(TTL) 의 900초(15분)입니다. 문서가 자동으로 삭제되는 시점은 다음과 같습니다. TTL 만료됩니다.
생성하려면 수신 버킷을 클릭하고 버킷 를 클릭한 다음 버킷 추가.
구성 수신 버킷을 클릭하고 버킷 추가.
- 이름수신
- 메모리 할당량256MB(참고: 임시 버킷은 디스크에 지속되지 않으므로 가져오는 전체 데이터 집합을 수용할 수 있도록 버킷에 충분한 메모리가 할당되어 있는지 확인해야 합니다. 이 예에서 사용된 댓글 및 동영상 컬렉션의 총 크기는 약 50MB이므로 이 데이터 집합을 수용하려면 256MB면 충분합니다.)
- 버킷 유형: 임시
- 고급 버킷 설정 -> 버킷 최대 수명 시간900초(참고: 문서가 Couchbase에 기록되는 동안 실시간으로 변환되므로 이 값을 상대적으로 낮게 설정할 수 있습니다. 이 경우 15분(900초)이 사용됩니다. 값을 너무 낮게 설정하면 문서가 처리되기 전에 만료될 수 있습니다.)
그리고 sample_mflix 버킷은 변환된 문서를 저장하는 데 사용됩니다. 이것은 카우치베이스 버킷 문서에 대한 영구 저장소가 필요하기 때문입니다. 다음과 같이 구성합니다:
- 이름: sample_mflix
- 메모리 할당량256MB(참고: 카우치베이스 버킷은 모든 문서를 디스크에 유지하므로 메모리 할당량에 따라 카우치베이스 버킷에 저장할 수 있는 문서 수가 결정됩니다. 통합 캐싱 레이어 를 사용할 수 있습니다. 이 예에서 사용된 댓글 및 동영상 컬렉션의 총 크기는 약 50MB이므로 256MB면 이 데이터 집합을 수용하기에 충분합니다.)
- 버킷 유형: Couchbase
그리고 오류 버킷은 변환할 수 없는 모든 문서를 저장하는 데 사용됩니다. 다음과 같이 구성합니다:
- 이름: 오류
- 메모리 할당량: 256 MB
- 버킷 유형: Couchbase
Eventing을 통한 데이터 혁신
이벤트 는 Couchbase로 데이터를 가져올 때 실시간으로 데이터를 변환하는 데 사용됩니다. 이 기능을 사용하려면 몇 가지 구성해야 할 사항이 있습니다.
먼저 메타데이터 버킷 이벤트가 시스템 데이터를 저장하는 데 사용됩니다. 다음과 같이 구성합니다:
- 이름: 메타데이터
- 메모리 할당량: 256 MB
- 버킷 유형: Couchbase
그리고 버킷 섹션에는 이제 오류, 수신, 메타데이터, sample_mflix 등 4개의 버킷이 나열됩니다:
를 클릭합니다. 이벤트 을 클릭한 다음 기능 추가 를 사용하여 데이터를 Couchbase로 가져올 때 실시간으로 변환하는 데 사용되는 함수를 구성할 수 있습니다.
다음과 같이 기능을 구성합니다:
- 소스 버킷수신(이 버킷은 Couchbase로 문서를 가져올 때 임시로 저장합니다.)
- 메타데이터 버킷메타데이터(이 버킷은 시스템 데이터를 저장하는 데 사용됨)
- 함수 이름: 변환
- 설명: MongoDB 내보내기 변환
- 바인딩 (를 클릭합니다. + 아이콘을 클릭하여 두 번째 바인딩을 추가합니다)
- 바인딩 유형: 버킷 별칭
- 별칭 이름대상(버킷을 참조하기 위해 함수에서 사용되는 별칭)
- 버킷: sample_mflix(클러스터의 버킷 이름)
- 액세스: 읽기 및 쓰기
-
- 바인딩 유형: 버킷 별칭
- 별칭 이름오류(버킷을 참조하기 위해 함수에서 사용되는 별칭)
- 버킷: 오류(클러스터의 버킷 이름)
- 액세스: 읽기 및 쓰기
클릭 다음: 코드 추가 에 대한 자바스크립트 코드를 추가하려면 변환 함수입니다.
변환 함수 화면에서 상용구 코드를 아래 코드로 바꿉니다.
이 함수에는 원본 문서, 변환된 문서 및 모든 오류를 기록하는 log() 문이 포함되어 있습니다. 필요에 따라 자유롭게 변경하세요. 이벤트 로그 파일은 @eventing 애플리케이션 로그에서 eventing.log 항목을 찾을 수 있습니다. 다음을 참조하세요. 이 링크 를 참조하여 로그 파일의 이름과 보기 방법에 대한 자세한 내용을 확인하세요.
transformValues() 함수에 필요한 코드를 추가하여 다른 변환을 수행하도록 이 함수의 기능을 쉽게 확장할 수 있습니다. 함수를 변경해야 하는 경우 다음을 수행해야 합니다. 일시 중지하거나 배포를 취소하고 JavaScript를 편집한 다음 다시 시작하거나 배포합니다..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
함수 온업데이트(doc, 메타) { 로그("원본 문서: ", doc); 시도 { // 문서 변환 var newDoc = transformValues(null, "", doc); // 문서 ID를 기반으로 유형 속성 추가(meta.id에서 사용 가능) newDoc["type"] = getTypeFromId(메타.id); // 유형과 _id 속성 값을 기반으로 변환된 문서의 문서 ID를 생성합니다. var id = generateId(newDoc); 로그("변환된 문서 (ID = " + id + "): ", newDoc); // 생성된 ID로 대상 버킷에 변환된 문서 쓰기 대상[id] = newDoc; } catch (e) { 로그("문서 변환 오류" + 메타.id + ". 자세한 내용은 오류 버킷을 참조하세요."); // 오류가 있는 경우 오류 속성에 오류 메시지를 저장합니다. doc["오류"] = e; // 원본 ID로 변환되지 않은 문서를 오류 버킷에 쓰기 오류[메타.id] = doc; } } 함수 OnDelete(메타) { } // 문서의 모든 프로퍼티(배열 및 하위 객체 포함)를 반복하는 재귀 함수입니다. // 확장 JSON을 표준 JSON으로 변환합니다. 함수 transformValues(부모 오브젝트, 부모 프로퍼티, 객체) { var 속성 유형 = ""; // 객체의 모든 프로퍼티에 대해 에 대한 (var 속성 in 객체) { 만약 (객체.hasOwnProperty(속성) && 객체[속성] != null) { 스위치 (속성) { case "$oid": // convert parentObj.parentProperty = {"$oid":"3487634876"} // 부모 오브젝트에 부모 오브젝트 속성 = "3487634876" 부모 오브젝트[부모 프로퍼티] = 객체[속성]; break; case "$date": 만약 (객체["$date"]["$numberLong"] != null) { // convert parentObj.parentProperty = {"$date":{"$numberLong":"-2418768000000"}} // 부모 오브젝트에 부모 오브젝트 속성 = -2418768000000 부모 오브젝트[부모 프로퍼티] = 번호(객체["$date"]["$numberLong"]); break; } // convert parentObj.parentProperty = {"$date":"1983-04-27T20:39:15Z"}} // 부모 오브젝트에 부모 오브젝트 속성 = "1983-04-27T20:39:15Z" 부모 오브젝트[부모 프로퍼티] = 객체["$date"]; break; case "$numberInt": case "$numberDecimal": case "$numberLong": case "$numberDouble": // convert parentObj.parentProperty = {"$numberInt":"1"} // 부모 오브젝트 부모 속성 = 1로 변경 부모 오브젝트[부모 프로퍼티] = 번호(객체[속성]); break; // !!! 이 함수는 여기에 대소문자를 추가하여 확장할 수 있습니다 !!! 기본값: // 그렇지 않으면 속성 유형을 확인합니다. 속성 유형 = 결정 유형(객체[속성]); 스위치 (속성 유형) { case "Object": // 프로퍼티가 객체인 경우 객체를 재귀적으로 변환합니다. transformValues(객체, 속성, 객체[속성]); break; case "배열": // 프로퍼티가 배열인 경우 배열의 모든 요소를 변환합니다. transformArray(객체[속성]); break; 기본값: // 그렇지 않으면 아무것도 하지 않습니다. break; } } } } 반환 객체; } // 지정된 객체의 유형을 확인합니다. 함수 결정 유형(객체) { 반환 객체 == null ? "null" : 객체.생성자.이름; } // 지정된 배열의 모든 요소 변환 함수 transformArray(객체) { 에 대한 (var i = 0; i < 객체.길이; i++) { transformValues(객체, i, 객체[i]); } } // 지정된 ID에서 문서 유형을 가져옵니다. // 이 함수는 다음 형식의 ID로 문서를 가져올 것으로 예상합니다: // 예시: :12 함수 getTypeFromId(id) { 반환 id.분할(":")[0]; } // 지정한 문서의 문서 ID를 생성합니다. // 새 ID는 type 속성의 값과 _id 속성의 값을 기반으로 합니다: // : 함수 generateId(문서) { var documentId = 문서["_id"]; 만약 (결정 유형(documentId) != "문자열") { throw "'_id' 값은 문자열이어야 합니다: _id = '" + documentId + "'"; } 반환 문서["type"] + ":" + documentId; } |
클릭 저장 를 클릭하여 코드를 저장하고 < 이벤트로 돌아가기 로 돌아가려면 이벤트 섹션으로 이동합니다.
새로운 변환 함수를 사용할 수 있지만 배포해야 합니다. 배포하려면 변환 기능을 클릭한 다음 배포.
를 클릭하여 기본 설정으로 기능 배포를 확인합니다. 배포 기능.
함수가 배포된 후 상태는 다음과 같습니다. 배포.
이제 모든 준비가 완료되었으므로 MongoDB 내보내기 데이터를 Couchbase로 가져와서 실시간으로 변환할 수 있습니다.
cbimport로 문서 가져오기
사용 cbimport 유틸리티 를 사용하여 MongoDB 내보내기 파일을 가져옵니다. 데이터를 가져오기 전에 명령 구문과 명령이 수행하는 작업을 이해하는 것이 중요합니다.
다음은 cbimport 명령의 예입니다:
1 |
$ cbimport json -c <클러스터> -u <관리자 사용자 이름> -p <관리자 비밀번호> -b <버킷> -d <가져오기 파일> -f <파일 형식> -g <키 생성기> |
몽고DB를 가져오려면 댓글 컬렉션을 찾으려면 아래 명령을 실행하세요. cbimport 유틸리티의 위치는 OS에 따라 다르며 여기에 설명되어 있습니다: CLI 참조.
1 |
$ <경로_to_cbimport>/cbimport json -c <클러스터> -u <관리자 사용자 이름> -p <관리자 비밀번호> -b 수신 -d 파일:///comments.json -f list -g comment:#MONO_INCR# |
이 명령은 제공된 관리자 자격 증명(예: -u 관리자 -p 비밀번호)을 사용하여 지정된 클러스터(예: -c couchbase://127.0.0.1)에 연결합니다.
이 명령은 comments.json에서 JSON 데이터를 가져옵니다. 내보낸 comments.json 파일의 형식을 확인하고 올바른 데이터 세트 형식 옵션 내보내기 파일 형식을 기반으로 합니다. 내보내기 파일은 목록 형식 목록의 각 요소가 별도의 문서를 나타내는 단일 JSON 목록을 포함합니다(-f 목록).
문서는 지정된 형식(-g comment:#MONO_INCR#)으로 생성된 키를 사용하여 수신 버킷(-b incoming)에 기록됩니다. 이 명령에서 형식은 각 문서 키가 "comment:"로 시작하도록 지정합니다. 이 명령의 MONO_INCR 함수 는 호출될 때마다 1씩 증가하므로 결과 키는 주석:1, 주석:2 등이 됩니다.
완료되면 다음과 같은 출력이 표시됩니다:
1 2 |
Json `파일://comments.json`을 `http://127.0.0.1:8091`으로 성공적으로 가져왔습니다. 문서 가져온: 50304 문서 실패: 0 |
로 이동합니다. 버킷 섹션에서 sample_mflix 버킷에는 50,304개의 문서가 들어 있습니다.
몽고DB를 가져오려면 영화 컬렉션에서 아래 명령을 실행합니다.
1 |
$ <경로_to_cbimport>/cbimport json -c <클러스터> -u <관리자 사용자 이름> -p <관리자 비밀번호> -b 수신 -d 파일:///movies.json -f list -g movie:#MONO_INCR# |
완료되면 다음과 같은 출력이 표시됩니다:
1 2 |
Json `파일://movies.json`을 `http://127.0.0.1:8091`으로 성공적으로 가져왔습니다. 문서 가져온: 23539 문서 실패: 0 |
로 이동합니다. 버킷 섹션에서 sample_mflix 버킷에는 73,843개의 문서가 들어 있습니다.
이제 변환된 문서 두 개를 확인합니다. 변환된 문서의 문서 섹션에서 버킷 로 설정되어 있습니다. sample_mflix. 아이디를 클릭합니다. comment:5a9427648b0beebeb69579cc (목록의 첫 번째 문서):
내용을 참고하세요:
1 2 3 4 5 6 7 8 9 |
{ "_id": "5a9427648b0beebeb69579cc", "name": "Andrea Le", "이메일": "andrea_le@fakegmail.com", "movie_id": "573a1390f29313caabcd418c", "text": "렘 오피시스 에아케 레펠렌두스 아메트 에오스 도롤리부스. 포로 돌로르 볼루파툼 볼루파테스 네케 쿨파 몰레스티아스. 볼루파테 운데 누라 템리부스 울람.", "date": "2012-03-26T23:20:16Z", "type": "댓글" } |
내보낸 데이터와 비교합니다(comments.json에서 5a9427648b0beebeb69579cc 검색):
1 2 3 4 5 6 7 8 |
{ "_id":{"$oid":"5a9427648b0beebeb69579cc"}, "name":"Andrea Le", "이메일":"andrea_le@fakegmail.com", "movie_id":{"$oid":"573a1390f29313caabcd418c"}, "text":"렘 오피시스 에아케 레펠렌두스 아메트 에오스 도롤리부스. 포로 돌로르 볼루파툼 볼루파테스 네케 쿨파 몰레스티아스. 볼루파테 운데 누라 템리부스 울람.", "date": {"$date": "2012-03-26T23:20:16Z"} } |
변환 함수는 확장 JSON _id, movie_id 및 날짜 값을 변경했습니다. 문서 키 접두사를 기반으로 유형 속성이 추가되었습니다(데이터를 가져올 때 키 접두사로 comment를 지정한 것을 기억하세요).
문서 내용 검토를 마치면 문서 편집기를 닫습니다.
에서 문서 ID 필드 입력 movie:573a1390f29313caabcd4135를 클릭하고 문서 검색를 클릭하고 아이디 movie:573a1390f29313caabcd4135.
내용을 참고하세요:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "_id": "573a1390f29313caabcd4135", "plot": "세 남자가 모루에 망치를 두드리며 ...", "장르": [ "짧은" ], "런타임": 1, "cast": [ "찰스 카이저", "존 오트" ], "num_mflix_comments": 1, "title": "대장장이 장면", "fullplot": "고정된 카메라가 큰 모루를 바라보고 있습니다...", "국가": [ "USA" ], "출시": -2418768000000, "디렉터": [ "윌리엄 K.L. 딕슨" ], "rated": "UNRATED", "awards": { "wins": 1, "후보": 0, "text": "1승." }, "lastupdated": "2015-08-26 00:03:50.133000000", "year": 1893, "imdb": { "rating": 6.2, "votes": 1189, "id": 5 }, "type": "movie", "토마토": { "viewer": { "rating": 3, "numReviews": 184, "미터": 32 }, "lastUpdated": "2015-06-28T18:34:09Z" } } |
내보낸 데이터와 비교합니다(movies.json에서 573a1390f29313caabcd4135 검색):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "_id": {"$oid": "573a1390f29313caabcd4135"}, "plot": "세 남자가 망치질하는 ...", "장르": [ "짧은" ], "런타임": 1, "cast": [ "찰스 카이저", "존 오트" ], "num_mflix_comments": 1, "title": "대장장이 장면", "fullplot": "고정된 카메라가 큰 모루를 바라보고 있습니다...", "국가": [ "USA" ], "출시": {"$date": {"$numberLong": "-2418768000000"}}, "디렉터":[ "윌리엄 K.L. 딕슨" ], "rated": "UNRATED", "awards": { "wins": 1, "후보": 0, "text": "1승." }, "lastupdated": "2015-08-26 00:03:50.133000000", "year": 1893, "imdb": { "rating": 6.2, "votes": 1189, "id": 5 }, "type": "movie", "토마토": { "viewer": { "rating": 3, "numReviews" 184, "미터": 32 }, "lastUpdated": {"$date": "2015-06-28T18:34:09Z"} } } |
transform 함수가 확장 JSON _id, released, & tomatoes.lastUpdated 값을 변경했습니다. 이 경우 유형 속성이 추가되지 않았습니다. 내보낸 문서에 이미 유형 속성이 포함되어 있었기 때문에 transform 함수는 유형 속성을 추가하지 않고 키 접두사를 기반으로 값을 설정했습니다(데이터를 가져올 때 키 접두사로 movie를 지정한 것을 기억하세요).
문서 내용 검토를 마치면 문서 편집기를 닫습니다.
다음 단계
더 이상 MongoDB 내보내기 데이터를 가져오지 않을 계획이라면 변환 함수를 배포 취소하고 수신 및 오류 버킷을 제거할 수 있습니다.
-
- 향후 글에서는 기존 클라이언트 코드를 업데이트하여 Couchbase SDK를 사용하는 방법에 대해 다룰 예정입니다.
- 다음에서 제공되는 무료 온라인 교육을 활용하세요. https://learn.couchbase.com 를 클릭하여 Couchbase에 대해 자세히 알아보세요.
- 다양한 카우치베이스 개발자 IDE - JetBrains, VSCode-플러그인이 있습니다.
CouchBase와 MongoDB의 서로 다른 문서 모델, 데이터 모델링 및 MongoDB 스키마에 대한 자세한 정보, 그리고 MongoDB와 CouchBase를 비교하는 다른 방법에 대해서는 이 문서를 참조하세요: 카우치베이스: 모든 면에서 몽고DB보다 나은 카우치베이스.
다른 기업들이 MongoDB 대신 Couchbase를 선택하는 이유를 알아보세요: