프롤로그
그리고 이전 기사 에서 MongoDB 데이터 세트를 Couchbase Server로 마이그레이션하는 방법에 대한 자세한 내용을 제공했습니다. 이 문서에서는 Couchbase SDK를 사용하여 Java 콘솔 애플리케이션을 통해 데이터에 액세스하는 방법을 보여줍니다. 코드 스니펫은 Couchbase 클러스터에 연결하고, 키/값 연산을 수행하고, N1QL 쿼리를 통해 보조 조회를 실행하는 방법을 Mongo Java SDK에서 동일한 작업을 수행하는 해당 코드와 함께 나란히 보여 줍니다.
이 블로그의 모든 코드는 다음 Git 리포지토리에서 사용할 수 있습니다: 몽고DB-카우치베이스.
전제 조건
의 세부 정보에 따라 데이터 세트가 포함된 Couchbase 클러스터입니다. 이전 기사.
애플리케이션 사용자 만들기
클라이언트(애플리케이션)가 Couchbase Server 클러스터에 연결하려면 먼저 클라이언트에서 인증에 사용할 애플리케이션 사용자를 정의해야 합니다. Couchbase 역할 기반 액세스 제어 를 사용하면 사용자를 정의하고 적절한 역할을 할당할 수 있습니다. 웹 콘솔을 사용하여 다음과 같은 애플리케이션 사용자를 만듭니다. 엠플릭스_클라이언트 를 다음과 같이 설정합니다.
로 이동합니다. 보안 섹션에서 웹 콘솔의 사용자 추가:
구성 엠플릭스_클라이언트 사용자를 다음과 같이 설정하고 사용자 추가:
- 사용자 이름: 엠플릭스_클라이언트
- 비밀번호비밀번호(또는 원하는 비밀번호)를 입력합니다.
- 비밀번호 확인다음과 동일 비밀번호 값을 설정합니다.
- 역할: 확장 sample_mflix 섹션에서 애플리케이션 액세스. . 애플리케이션 액세스 역할 샘플_mflix 버킷의 모든 데이터에 대한 전체 읽기 및 쓰기 권한을 갖습니다. 이 역할은 사용자가 아닌 애플리케이션을 위한 것으로, Couchbase 웹 콘솔에 대한 액세스는 허용하지 않습니다.
에서 보안 섹션에 새 mflix_client 사용자가 표시됩니다:
N1QL 쿼리에 대한 인덱스 생성
보조 색인 는 MongoDB의 인덱스처럼 쿼리(또는 보조 조회)의 효율적인 실행을 지원합니다. 이 문서의 코드 샘플은 다음을 실행합니다. N1QL 쿼리 두 개의 인덱스를 사용하는 N1QL 쿼리를 실행하여 생성할 수 있습니다. 인덱스의 쿼리 섹션으로 이동합니다:
첫 번째 인덱스는 sample_mflix 버킷에 있는 모든 댓글 문서의 이름 속성에 있습니다. 다음 N1QL 문을 쿼리 편집기:
1 |
만들기 INDEX idx1 on sample_mflix(이름) 어디 유형="댓글" |
클릭 실행 그리고 잠시 후 인덱스 생성 가 완료되었습니다:
두 번째 인덱스는 sample_mflix 버킷에 있는 모든 영화 문서의 연도, imdb.rating, 제목 속성에 대한 인덱스입니다. 다음 N1QL 문을 쿼리 편집기:
1 |
만들기 INDEX idx2 on sample_mflix(년, imdb.평가, title) 어디 유형="movie" |
클릭 실행 를 입력하면 잠시 후 인덱스 생성이 완료됩니다:
로 이동합니다. 색인 섹션에서 인덱스가 있는지 확인합니다. idx1 & idx2 존재합니다:
MongoDB API 호출을 Couchbase API 호출로 변환하기
이 문서의 샘플 코드는 Couchbase 및 MongoDB Java SDK를 사용하며 일부 SDK API를 사용하는 방법의 예시로만 제공됩니다. 해당 언어의 Couchbase SDK 설명서 전문은 다음 링크를 참조하세요:
카우치베이스 서버에 연결
클러스터 리소스에 액세스하려면 클라이언트는 다음을 수행해야 합니다. 인증 에 적절한 자격 증명을 전달하여 인증합니다. 샘플 코드는 위에서 생성한 mflix_client 애플리케이션 사용자 자격 증명을 사용하여 인증합니다.
다음 코드 샘플은 지정된 노드에서 실행 중인 Couchbase 클러스터에 연결하고, mflix_client 버킷에 대한 참조와 해당 버킷의 기본 컬렉션에 대한 참조를 가져옵니다.
카우치베이스
1 2 3 |
클러스터 클러스터 = 클러스터.연결("127.0.0.1", "mflix_client", "비밀번호"); 버킷 버킷 = 클러스터.버킷("sample_mflix"); 컬렉션 컬렉션 = 버킷.기본 컬렉션(); |
MongoDB
1 2 3 4 |
몽고클라이언트 몽고클라이언트 = 몽고클라이언트.create("mongodb+srv://:@/ "); 몽고 데이터베이스 몽고 데이터베이스 = 몽고클라이언트.getDatabase("sample_mflix"); 몽고컬렉션<Document> 댓글 = 몽고 데이터베이스.getCollection("댓글"); 몽고컬렉션<Document> 영화 = 몽고 데이터베이스.getCollection("영화"); |
ID로 문서 검색
사용 Collection.get() 메서드를 전체 문서 검색 를 검색합니다. 다음 코드 샘플은 sample_mflix 버킷 기본 컬렉션에서 두 개의 문서를 검색합니다.
카우치베이스
1 2 3 4 5 6 |
// get()은 지정된 ID를 가진 문서가 존재하지 않으면 예외를 발생시킵니다. GetResult 댓글 = 컬렉션.get("comment:5a9427648b0beebeb69579cc"); 시스템.out.println(댓글.contentAsObject()); GetResult 영화 = 컬렉션.get("movie:573a1390f29313caabcd4135"); 시스템.out.println(영화.contentAsObject()); |
MongoDB
1 2 |
댓글.찾기(필터.eq("_id", new ObjectId("5a9427648b0beebeb69579cc"))); 영화.찾기(필터.eq("_id", new ObjectId("573a1390f29313caabcd4135"))); |
새 문서 삽입
사용 Collection.insert() 메서드를 새 문서 만들기 가 아직 존재하지 않는 경우 지정된 ID 및 콘텐츠로 채워집니다. 다음 코드 샘플은 sample_mflix 버킷 기본 컬렉션에 이 문서를 삽입합니다:
1 2 3 4 5 6 7 |
{ "name":"아나트 체이스", "이메일":"anat_chase@fakegmail.com", "movie_id":"movie:573a1390f29313caabcd4135", "text":"아나트의 리뷰입니다", "type":"댓글" } |
카우치베이스
1 2 3 4 5 6 7 8 9 |
JsonObject doc = JsonObject.create() .put("name", "아나트 체이스") .put("이메일", "anat_chase@fakegmail.com") .put("movie_id", "movie:573a1390f29313caabcd4135") .put("text", "아나트의 리뷰입니다") .put("type", "댓글"); // insert()는 지정된 ID를 가진 문서가 이미 존재하는 경우 예외를 발생시킵니다. 컬렉션.삽입("comment:5a9427648b0beebeb69579c0", doc); |
MongoDB
1 2 3 4 5 6 7 |
문서 doc = new 문서("_id", new ObjectId("5a9427648b0beebeb69579c0")) .추가("name", "아나트 체이스") .추가("이메일", "anat_chase@fakegmail.com") .추가("movie_id", new ObjectId("573a1390f29313caabcd4135")) .추가("text", "아나트의 리뷰입니다"); 댓글.insertOne(doc); |
여러 개의 새 문서 삽입
일괄 처리 작업 를 사용하면 네트워크 처리량을 늘리고 지연 시간을 줄임으로써 네트워크 활용도를 높이고 애플리케이션 속도를 높일 수 있습니다. 일괄 처리 작업은 다음과 같이 작동합니다. 파이프라인 요청을 네트워크를 통해 전송합니다. 요청이 파이프라인으로 전송되면 하나의 큰 그룹으로 클러스터로 전송됩니다. 클러스터는 차례로 파이프라인 응답을 클라이언트에 다시 보냅니다.
다음 코드 샘플은 이 접근 방식을 사용하여 sample_mflix 버킷에 두 개의 새 문서를 삽입합니다.
카우치베이스
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 |
// 두 개의 JSON 문서 생성 목록<Tuple2<문자열, JsonObject>> 문서 = new ArrayList<Tuple2<문자열, JsonObject>>(); doc = JsonObject.create() .put("name", "아나트 체이스") .put("이메일", "anat_chase@fakegmail.com") .put("movie_id", "movie:573a1390f29313caabcd42e8") .put("text", "아나트의 리뷰입니다") .put("type", "댓글"); 문서.추가(튜플.의("comment:5a9427648b0beebeb69579c1", doc)); JsonObject doc2 = JsonObject.create() .put("name", "아나트 체이스") .put("이메일", "anat_chase@fakegmail.com") .put("movie_id", "movie:573a1390f29313caabcd4323") .put("text", "아나트의 리뷰입니다") .put("type", "댓글"); 문서.추가(튜플.의("comment:5a9427648b0beebeb69579c2", doc2)); // 마지막 문서가 완료될 때까지 기다리면서 2개의 문서를 한꺼번에 삽입합니다. // insert()는 지정된 ID를 가진 문서가 이미 존재하는 경우 예외를 발생시킵니다. 플럭스 .에서이터러블(문서) .병렬().runOn(스케줄러.탄력적()) .concatMap(doc3 -> 반응형 컬렉션.삽입(doc3.getT1(), doc3.getT2()) .onErrorResume(e -> Mono.오류(new 예외(doc3.getT1(), e)))) .순차적().collectList().블록(); |
MongoDB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
목록<Document> 문서 = new ArrayList<Document>(); 문서 doc1 = new 문서("_id", new ObjectId("5a9427648b0beebeb69579c1")) .추가("name", "아나트 체이스") .추가("이메일", "anat_chase@fakegmail.com") .추가("movie_id", new ObjectId("573a1390f29313caabcd42e8")) .추가("text", "아나트의 리뷰입니다"); 문서.추가(doc1); 문서 doc2 = new 문서("_id", new ObjectId("5a9427648b0beebeb69579c2")) .추가("name", "아나트 체이스") .추가("이메일", "anat_chase@fakegmail.com") .추가("movie_id", new ObjectId("573a1390f29313caabcd4323")) .추가("text", "아나트의 리뷰입니다"); 문서.추가(doc2); 댓글.insertMany(문서); |
기존 문서 업데이트
사용 Collection.replace() 메서드를 기존 문서 업데이트 가 이미 존재하는 경우에만 지정된 ID를 사용합니다. 카우치베이스 지원 하위 문서 작업 에 효율적으로 액세스하는 데 사용할 수 있습니다. 부품 문서 수를 줄일 수 있습니다. 하위 문서 작업은 다음보다 더 빠르고 네트워크 효율이 높을 수 있습니다. 전체 문서 작업은 네트워크를 통해 문서의 액세스된 부분만 전송하기 때문입니다. 전체 문서 및 하위 문서 작업은 원자적이어서 동시성 제어 기능이 내장된 문서를 안전하게 수정할 수 있습니다.
다음 코드 샘플은 하위 문서 작업을 사용하여 지정된 문서의 텍스트 속성을 업데이트합니다.
카우치베이스
1 2 3 4 5 |
// 하위 문서 API를 사용하여 문서를 업데이트하여 특정 속성을 수정합니다. // replace()는 지정된 ID의 문서가 존재하지 않으면 예외를 발생시킵니다. 컬렉션.mutateIn( "comment:5a9427648b0beebeb69579c0", 배열.asList(대체("text", "이것은 Anat의 리뷰가 아닙니다."))); |
MongoDB
1 2 3 |
댓글.updateOne( 필터.eq("_id", new ObjectId("5a9427648b0beebeb69579c0")), 업데이트.결합(업데이트.set("text", ""))); |
여러 문서 업데이트
키/값 API를 통한 기본 액세스 외에도 다음을 수행할 수 있습니다. N1QL 쿼리 실행 N1QL API를 통해 N1QL 은 JSON 데이터를 쿼리, 변환, 조작하기 위한 선언적 언어입니다(JSON용 SQL이라고 생각하시면 됩니다).
다음 코드 샘플은 N1QL 쿼리를 실행하여 이름이 Anat Chase인 모든 댓글 문서의 이름 및 이메일 속성을 업데이트합니다. 이 쿼리는 idx1 인덱스를 생성합니다.
카우치베이스
1 2 3 4 5 6 |
// 쿼리 API를 통해 N1QL 업데이트 쿼리를 실행합니다. 문자열 문 = "업데이트 샘플_mflix " + "SET name='Anita Chase', email='anita_chase@fakegmail.com' " + "WHERE type='comment' AND name='Anat Chase'"; QueryResult 업데이트 결과 = 클러스터.쿼리(문); |
MongoDB
1 2 3 4 5 |
댓글.updateMany( 필터.eq("name", "아나트 체이스"), 업데이트.결합( 업데이트.set("name", "아니타 체이스"), 업데이트.set("이메일", "anita_chase@fakegmail.com"))); |
문서 업데이트 또는 삽입
사용 Collection.upsert() 메서드를 문서가 없는 경우 삽입하고, 있는 경우 대체합니다.. 지정된 ID를 가진 문서가 없는 경우 upsert()는 새 문서를 만듭니다. 지정된 ID를 가진 문서가 존재하면 upsert()는 기존 문서를 업데이트합니다. 다음 코드 샘플은 sample_mflix 버킷에 있는 기존 문서를 업데이트합니다.
카우치베이스
1 2 3 4 5 6 7 8 9 |
doc = JsonObject.create() .put("name", "미아 한나스") .put("이메일", "mia_hannas@fakegmail.com") .put("movie_id", "movie:573a1390f29313caabcd4135") .put("text", "미아의 리뷰입니다") .put("type", "댓글"); // upsert()는 문서가 있으면 문서를 업데이트하고 문서가 없으면 삽입합니다. 컬렉션.업서트("comment:5a9427648b0beebeb69579c0", doc); |
MongoDB
1 2 3 4 5 6 7 |
컬렉션.replaceOne( 필터.eq("_id", new ObjectId("5a9427648b0beebeb69579c0")), new 문서("name", "미아 한나스") .추가("이메일", "mia_hannas@fakegmail.com") .추가("movie_id", new ObjectId("573a1390f29313caabcd4135")) .추가("text", "미아의 리뷰입니다"), new 업데이트 옵션().업서트(true)); |
문서 삭제
사용 Collection.remove() 메서드를 전체 문서 제거 버킷에 지정된 ID를 추가합니다. 다음 코드 샘플은 sample_mflix 버킷에서 기존 문서를 삭제합니다.
카우치베이스
1 2 |
// remove()는 문서가 존재하지 않으면 예외를 던집니다. 컬렉션.제거("comment:5a9427648b0beebeb69579c0"); |
MongoDB
1 |
컬렉션.deleteOne(필터.eq("_id", new ObjectId("5a9427648b0beebeb69579c0"))); |
여러 문서 삭제
N1QL 쿼리를 사용하여 문서를 삭제할 수도 있습니다. 다음 코드 샘플은 샘플_mflix 버킷에서 여러 문서를 삭제하기 위해 N1QL 쿼리를 실행합니다. 이름이 Anita Chase인 모든 댓글 문서가 삭제됩니다. 이 쿼리는 idx1 인덱스를 생성합니다.
카우치베이스
1 2 3 4 5 |
// 쿼리 API를 통해 N1QL DELETE 쿼리를 실행합니다. 문자열 문 = "DELETE FROM sample_mflix " + "WHERE type='comment' AND name='Anita Chase'"; QueryResult 삭제 결과 = 클러스터.쿼리(문); |
MongoDB
1 |
댓글.deleteMany(필터.eq("name", "아니타 체이스")); |
N1QL을 사용한 데이터 액세스
N1QL은 데이터의 보다 복잡한 2차 조회를 수행하는 데에도 사용할 수 있습니다. 다음 코드 샘플은 연도가 1970년에서 1979년 사이인 모든 영화 문서에서 제목, 연도 및 imdb.rating을 선택하기 위해 차단 N1QL 쿼리를 실행합니다(imdb.rating에 따라 정렬). 이 쿼리는 idx2 인덱스를 생성합니다.
다음과 유사 반응형 키/값 작업 일괄 처리, 반응형 및 비동기 쿼리 를 사용하여 성능을 향상시켜야 합니다.
카우치베이스
1 2 3 4 5 6 7 8 |
// 쿼리 API를 통해 N1QL SELECT 쿼리 실행(차단) 문자열 선택문 = "SELECT title, year, imdb.rating FROM sample_mflix " + "WHERE type='movie' AND 연도 1970년과 1979년 사이 ORDER BY imdb.rating DESC"; final QueryResult selectResult = 클러스터.쿼리(선택문); 에 대한 (JsonObject 행 : selectResult.rowsAsObject()) { 시스템.out.println(행.toString()); } |
MongoDB
1 2 3 4 5 |
영화.찾기(필터.그리고(필터.gte("year", 1970), 필터.lte("year", 1979))) .정렬(정렬.내림차순("imdb.rating")) .프로젝션(투영.필드( 투영.포함("title", "year", "imdb.rating"), 투영.excludeId())); |
다음 단계
다음을 포함한 Couchbase SDK의 다른 기능에 대해 알아보세요. 분석 그리고 전체 텍스트 검색. 다음에서 제공되는 무료 온라인 교육을 활용하세요. https://learn.couchbase.com 를 클릭하여 Couchbase에 대해 자세히 알아보세요.
MongoDB에 비해 Couchbase 데이터 플랫폼의 아키텍처적 장점에 대한 자세한 내용은 이 문서를 참조하세요: 카우치베이스: 모든 면에서 몽고DB보다 나은 카우치베이스.
다른 기업들이 MongoDB 대신 Couchbase를 선택하는 이유를 알아보세요: