참고: 모든 예제는 다음에서 확인할 수 있습니다. 여기.
오늘 저희는 곧 출시될 Couchbase Server의 새로운 기능에 대한 매우 특별한 개발자 프리뷰(DP)를 공개합니다. 하위 문서를 일반 Couchbase Server .NET SDK 2.2.6과 함께 출시합니다! 하위 문서 API는 Couchbase Server 4.5의 개발자 프리뷰에서 사용할 수 있는 Couchbase Server의 새로운 기능입니다.
기억하시겠지만, Couchbase에서 모든 문서 변경은 원자적이며 전체 문서와 관련이 있습니다. 단일 필드만 변경한 다음 업데이트를 수행하려는 경우 새 수정본에 의해 Couchbase 서버의 전체 문서가 복사됩니다. 문제는 문서가 크거나 네트워크가 느린 경우(또는 둘 다) 수정되지 않은 데이터를 전송하는 데 많은 리소스가 낭비된다는 것입니다. 더 나은 성능의 솔루션은 문서의 일부분 또는 변경된 값만 전송하는 것입니다. 기본적으로 하위 문서 API를 사용하면 문서의 요소를 업데이트하거나 요소를 삭제할 때 경로 를 유선으로 전송하면 문서의 해당 부분만 수정됩니다.
API에서 지원하는 작업에는 개별 중첩 요소의 변이부터 여러 가지가 있습니다. sub-문서를 배열 및 사전 수정에 사용할 수 있습니다. 카운터 연산도 지원되며, 임베디드 JSON 조각에 대한 검색 연산도 지원됩니다.
API는 유창한 인터페이스를 통해 노출되어 여러 연산을 추가한 다음 문서에 대해 원자적으로 실행할 수 있습니다. 변이 연산을 위한 빌더와 읽기 또는 '조회'를 위한 빌더, 주어진 경로에 요소가 존재하는지 확인하기 위한 빌더 등 두 가지 '빌더'가 있습니다.
중요: 하위 문서 API는 개발자 프리뷰입니다!!!
이것은 하위 문서 API의 초기 DP이며 일반적인 API가 릴리스 전에 거치는 일반적인 점검과 균형을 거치지 않았다는 점에 유의하세요. 또한 사용자 피드백에 따라 공개 인터페이스는 후속 릴리스에서 변경될 수 있으므로 아직은 프로덕션 환경에서 하위 문서 API를 사용하지 않는 것이 좋습니다. 그러나 2.2.6의 나머지 부분은 테스트를 마쳤으며 프로덕션 환경에서 사용할 수 있습니다.
전제 조건: Couchbase Server 4.5.0 개발자 프리뷰
아래 예시를 따르려면 다음을 다운로드하여 설치해야 합니다. Couchbase Server 4.5 개발자 미리 보기. 지금 바로 해보세요!
하위 문서 API DP 개요
다음 예제에서는 ID가 'puppy'인 문서를 사용하며 다음과 같이 표시됩니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "type": "dog", "breed": "핏불/치와와", "name": "강아지", "장난감": [ "squeaker", "ball", "shoe" ], "소유자": { "type": "servant", "name": "돈 노트", "age": 63 }, "속성": { "fleas": true, "color": "white", "eyeColor": "갈색", "age": 5, "더러운": true, "sex": "여성" } } |
모든 예제는 다음에서 확인할 수 있습니다. Github 를 사용하여 프로젝트를 복제하고 API를 사용해 볼 수 있습니다.
MutateInBuilder 및 룩업인빌더
앞서 언급했듯이 하위 문서 API는 문서에서 여러 작업을 연결하기 위해 유창한 인터페이스를 통해 빌더 패턴을 활용하는 두 가지 새로운 유형을 제공합니다. 두 개체 모두 MutateIn
또는 룩업인
에 카우치베이스버킷
객체를 생성하고 작업 중인 문서의 키 또는 ID를 전달합니다:
1 2 3 4 5 6 7 8 9 10 11 12 |
//기본 설정으로 클러스터 도우미를 초기화합니다(예: localhost). 클러스터 도우미.초기화(); var 버킷 = 클러스터 도우미.GetBucket("default"); //문서 "thekey"에 대한 변이 빌더를 생성합니다. var 돌연변이 = 버킷.MutateIn("thekey"); // "thekey2" 문서에 대한 조회 빌더를 만듭니다. var 조회 = 버킷.룩업인("thekey2"); 클러스터 도우미.닫기(); |
빌더 객체가 있으면 예를 들어 문서에 대해 실행할 여러 작업을 체인으로 연결할 수 있습니다:
1 2 3 4 5 6 |
var 빌더 = 버킷.룩업인(id). Get("type"). Get("name"). Get("소유자"). 존재("notfound"); |
그런 다음 모든 작업을 한 번에 서버로 전송할 수 있습니다:
1 2 |
var 조각 = 빌더.실행(); |
그런 다음 경로에 대한 한 가지 작업의 결과를 확인합니다. 유형
:
1 2 3 4 5 6 |
만약 (조각.OpStatus("type") == 응답 상태.성공) { 문자열 형식 = "Path='{0}' Value='{1}'"; 콘솔.WriteLine(형식, "type", 조각.콘텐츠("type")); } |
IDocumentFragment
이름 | 설명 |
---|---|
콘텐츠(...) | 지정된 경로 또는 인덱스의 콘텐츠를 가져옵니다. |
존재(...) | 지정된 경로 또는 인덱스에 대한 결과가 있는 경우 true를 반환합니다. |
Count() | 빌더가 유지 관리하는 현재 작업의 개수입니다. |
OpStatus(...) | 그리고 응답 상태 인덱스 또는 경로에서 작업을 수행합니다. |
상태 | 그리고 응답 상태 를 사용하여 전체 다중 작업을 수행합니다. |
성공 | 전체 다중 작업이 성공하면 참입니다. |
이러한 프로퍼티 또는 메서드 외에도 다음에서 상속된 다른 모든 프로퍼티가 있습니다. 작업 결과
는 K/V 작업의 표준 응답입니다: 업서트, 제거, 교체 등입니다.
오류 처리
여러 개의 조회를 전송할 때 그 중 하나가 실패하면 전체 다중 작업 요청이 실패하므로 단일 문서 내에서 조회를 수행할 때 트랜잭션의 전부 아니면 전무의 의미가 허용됩니다. 여러 조회를 전송할 때 서버는 요청된 만큼의 항목을 반환하려고 시도하면서 일부 작업이 성공하고 일부 작업이 실패할 수 있습니다. 작업이 실패하면 Status 속성에는 다음과 같은 최상위 오류 응답이 포함됩니다. 하위 문서 다중 경로 실패,
는 특정 오류를 얻기 위해 작업 결과를 더 자세히 조사하라는 표시입니다. OpStatus 메서드를 호출하고 인덱스 또는 경로를 전달하여 반복하면 이 작업을 수행할 수 있습니다:
1 2 3 4 5 6 7 8 9 10 11 12 |
var 빌더 = 버킷.룩업인(id). Get("type"). Get("일부 경로가 존재하지 않음"). Get("소유자"); var 조각 = 빌더.실행(); 콘솔.WriteLine("일반 오류입니다: {0}{1}특정 오류입니다: {2}", 조각.상태, 환경.뉴라인, 조각.OpStatus(1)); 콘솔.WriteLine("일반 오류입니다: {0}{1}특정 오류입니다: {2}", 조각.상태, 환경.뉴라인, 조각.OpStatus("일부 경로가 존재하지 않음")); |
이 경우 문서 내에 경로가 존재하지 않으므로 반환된 특정 오류는 다음과 같습니다. 하위 문서 경로를 찾을 수 없음
. 빌더 유형과 오류 조건에 따라 다양한 오류 조합이 있으며, 이는 간략하게 소개한 것으로 API를 시작하는 데 적합해야 합니다.
룩업인빌더 예제
룩업인빌더는 경로별 값 가져오기와 지정된 경로에서 값의 존재 여부 확인이라는 두 가지 작업을 지원합니다.
Get:
조회해 보겠습니다. 소유자
조각 기준 경로
:
1 2 3 4 5 6 |
var 빌더 = 버킷.룩업인(id). Get("소유자"). 실행(); var 소유자 = 빌더.콘텐츠("소유자"); |
출력은 다음과 같습니다:
1 2 3 4 5 6 |
{ "type": "servant", "name": "돈 노트", "age": 63 } |
존재합니다:
다음 사항을 확인해 보겠습니다. 소유자
경로가 존재합니다:
1 2 3 4 5 6 |
var 빌더 = 버킷.룩업인(id). 존재("소유자"). 실행(); var 발견 = 빌더.콘텐츠("소유자"); |
출력은 다음과 같습니다. true
경로 소유자
가 문서 내에 실제로 존재합니다.
뮤테이트인빌더
MutateInBuilder는 스칼라 값, 딕셔너리 및 배열의 변형을 지원하는 다양한 메서드와 원자 카운터 연산을 지원합니다.
삽입합니다:
삽입은 포함 요소(사전 자체)를 추가할 수 있도록 선택적으로 딕셔너리에 값을 추가합니다:
1 2 3 4 |
var 빌더 = 버킷.MutateIn(id). 삽입("attributes.hairLength", "short"). 실행(); |
이제 문서의 속성 사전은 다음과 같이 표시됩니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... "속성": { "fleas": true, "color": "white", "eyeColor": "갈색", "age": 5, "더러운": true, "sex": "여성", "hairLength": "short" } ... |
이제 부모 요소가 존재하지 않으면 createParents
매개변수를 사용하여 부모 요소를 만들 수 있습니다. 부모 요소가 존재하지 않는 경우 실패하려면 false를 전달하고, 부모 요소가 존재하지 않는 경우 실패하려면 true를 전달하면 됩니다:
1 2 3 4 |
var 빌더 = 버킷.MutateIn(id). 삽입("anewattribute.withakey", "일부값"). 실행(); |
그러면 다음과 같은 새 속성이 생성됩니다. 새로운 속성
라는 단일 키를 문서에 추가하고 withakey
값으로 일부값
.
1 2 3 4 5 6 7 |
... "anewattribute": { "withakey": "일부값" } ... |
이제 false
에 대한 createParents
로 설정되어 있고 부모 속성이 존재하지 않으면 다중 변이가 실패하고 최상위 응답 상태는 하위 문서 다중 경로 실패
구체적인 오류는 다음과 같습니다. 하위 문서 경로를 찾을 수 없음
.
Upsert
업서트는 기존 사전 항목을 추가하거나 바꿉니다. 사용법은 삽입
메서드 이름이 Upsert
.
제거
제거
는 지정된 경로에서 요소를 제거합니다. 예를 들어 위 문서에서 소유자의 이름을 제거하겠습니다:
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 제거("owner.name"). 실행(); |
그리고 호출 후 문서 제거
:
1 2 3 4 5 6 7 8 |
... "소유자": { "type": "servant", "age": 63 }, ... |
교체
바꾸기는 지정된 경로에서 요소의 값을 바꾸며, 경로가 존재하지 않으면 실패합니다:
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 교체("소유자", new { CatLover=true, 고양이 이름="celia"}). 실행(); |
이제 문서의 '소유자' 값이 달라집니다:
1 2 3 4 5 6 7 8 |
... "소유자": { "catLover": true, "catName": "celia" }, ... |
푸시백
배열의 뒷부분에 값을 추가하고, 부모 요소(배열 요소 자체)가 존재하지 않는 경우 선택적으로 추가합니다.
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 푸시백(경로, 값, false). 실행(); |
그리고 장난감
배열은 이제 마지막 서수에 "slipper" 값을 갖습니다:
1 2 3 4 5 6 7 8 9 10 |
... "장난감": [ "squeaker", "ball", "shoe", "slipper" ], ... |
푸시프론트
배열 앞에 값을 추가하고 부모 요소(배열 자체)가 존재하지 않는 경우 선택적으로 추가합니다:
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 푸시프론트(경로, 값, false). 실행(); |
그리고 장난감
배열은 이제 첫 번째 서수에 "slipper" 값을 갖습니다:
1 2 3 4 5 6 7 8 9 10 |
... "장난감": [ "slipper", "squeaker", "ball", "shoe" ], ... |
ArrayInsert
주어진 인덱스의 배열에 값을 삽입합니다:
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). ArrayInsert("장난감[2]", "slipper"). 실행(); |
그리고 장난감
배열은 이제 세 번째 서수(인덱스 2)에 "slipper" 값을 갖습니다:
1 2 3 4 5 6 7 8 |
"장난감": [ "squeaker", "ball", "slipper", "shoe" ], |
추가 고유
배열에 값을 삽입하며, 값이 존재하면 실패합니다(값은 배열 내에서 고유해야 합니다):
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 추가 고유("장난감", "shoe"). 실행(); |
"shoe" 값은 원본 문서의 장난감
배열을 사용하면 다음과 같은 상태로 실패합니다:
1 2 |
하위 문서 경로 존재 |
이 메서드에서는 문자열, 숫자, 참, 거짓 또는 null의 특수 값과 같은 JSON 기본 요소만 삽입할 수 있습니다. 그 이유는 각 JSON 객체로 내려가서 항목별로 요소를 비교하지 않고는 고유성을 비교할 수 있는 방법이 없기 때문입니다.
카운터
기존 값에 지정된 델타를 추가하여 요소가 없는 경우 요소를 생성하고 값과 델타를 0으로 기본 설정합니다. 델타가 음수이면 요소의 값은 지정된 델타만큼 감소합니다.
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 카운터("좋아요", 1). 실행(); |
요소가 존재하지 않으므로 생성된 다음 하나(1)로 설정됩니다. 이제 문서가 다음과 같이 표시됩니다:
1 2 3 4 5 |
... ], "좋아요": 1 } |
음수(-1)를 전달하면 다음 카운터는 좋아요
은 다시 0(0)으로 감소합니다:
1 2 3 4 |
var 조각 = 버킷.MutateIn(id). 카운터("좋아요", -1). 실행(); |
이제 JSON 문서는 다음과 같이 표시됩니다:
1 2 3 4 5 |
... ], "좋아요": 0 } |
v2.2.6 릴리스 노트
버그
- [NCBC-981] - 카우치베이스 인스턴스에 FQDN이 정의된 경우 SSL이 실패합니다.
- [NCBC-1074] - 동기식으로 대기하는 경우 요청 차단을 무기한으로 보기
- [NCBC-1083] - 풀컨피규레이션은 재정의해도 여전히 기본 설정을 사용합니다.
- [NCBC-1084] - ConfigSection은 UseSsl을 무시합니다.
- [NCBC-1086] - 문서가 잠겨있을 때 잠금 상태를 반환하지 않고 시간 초과된 GetAndLock
개선 사항
- [NCBC-1070] - QueryRequest가 JSON.NET에 종속되지 않도록 만들기
- [NCBC-1082] - QueryResult.Metrics에서 sortCount에 대한 지원 추가
- [NCBC-1085] - 실행 스레드가 차단되지 않도록 콜백을 기다립니다.
- [NCBC-1090] - SSL IO에서 "캐치 절 본문에서 대기할 수 없음" 수정
새로운 기능
- [NCBC-998] - 하위 문서 API 지원 포함 - 파트 1 다중 명령 DP
v2.2.6을 다운로드하는 방법
- 바이너리 다운로드 여기를 클릭하세요.
- NuGet 패키지는 다음에서 찾을 수 있습니다. 여기.
- 깃허브 리포지토리는 다음과 같습니다. 여기.