오늘 한 개발자로부터 다른 것에서 Couchbase로 마이그레이션하려는 질문이 들어왔습니다. 그 '다른 것'에는 일부 메타데이터가 포함된 JSON 문서가 있었습니다. Couchbase는 몇 가지 좋은 이유로 데이터를 메타데이터와 분리하므로 이 "_id" 필드를 제거해야 합니다. 다행히도 이 작업을 수행하는 확장 메서드를 작성하는 것은 매우 쉽습니다. .NET SDK를 사용하거나 POCO(Plan Ole의 Csharp 객체)를 사용하는 경우 사용자 지정 ContractResolver를 사용하세요.
시나리오
다음과 같이 생긴 문서가 디스크에 저장되어 있다고 가정해 보겠습니다:
원하는 것은 문서 자체에서 ID를 손쉽게 제거하고 이를 Couchbase에 삽입할 문서의 키로 만드는 것입니다. 이 작업이 완료되면 문서 자체와 문서 메타데이터라는 두 개의 문서가 Couchbase에 저장됩니다.
문서 메타데이터? 콘텐츠? 차이점은 무엇인가요?
메타데이터 는 문서 자체에 대한 데이터이지만 문서 콘텐츠에 대한 데이터는 아닙니다. 여기에는 다음과 같은 값이 포함됩니다:
- TTL - 문서의 만료 시간
- CAS - 키에서 최적의 동시성을 보장하기 위해 값을 비교하고 스왑합니다.
- 플래그 - 트랜스코딩을 위한 SDK별 메타데이터
- 시퀀스 번호 - 다른 클러스터에서 업데이트되는 키의 충돌 해결을 위해 Couchbase 내에서 내부적으로 사용되는 값 - 사물 교차 데이터 센터 복제(XDCR)
- 키 - 문서 자체의 고유 식별자
이 모든 정보는 콘텐츠 자체 외부에서 유용하므로 분리되어 메모리에 유지되는 것이 중요합니다. 메타데이터 크기는 카우치베이스 버전마다 다르지만 2.1.0 버전에서는 54k로 상당히 작습니다. 이제 문서의 콘텐츠는 실제 JSON 또는 바이너리 데이터 자체입니다.
확장 메서드와 함께 사용자 지정 컨트랙트 리졸버 사용
문서에서 "_id"의 키 값을 가져오는 것과 직렬화 중에 "_id" 값이 콘텐츠와 함께 유지되지 않도록 하는 것 두 가지가 필요합니다. 전자의 경우 JSON 문자열을 파싱하여 "_Id"를 추출한 다음 이를 Couchbase에 삽입할 새 문서에 할당해야 합니다. 후자는 두 가지 방법 중 하나를 사용할 수 있습니다: 사용자 정의 ContractResolver를 사용하거나 JSON을 JObject 자체로 조작하는 것입니다. POCO와 동적 키워드를 모두 지원하려면 두 가지를 모두 수행해야 합니다.
무시 필드 컨트랙트 해결사
Couchbase .NET SDK는 기본적으로 뉴턴소프트 JSON 프레임워크 를 사용할 수 있습니다. 클라이언트를 구성할 때 사용자 정의 계약 해석기를 할당하기 위한 후크가 있습니다. 컨트랙트는 JSON의 필드에서 객체 모델로 해석됩니다. 사용자 정의 리졸버를 사용하면 JSON 내의 필드를 무시하거나 수정하는 등의 작업을 수행할 수 있으며, 일종의 필터처럼 작동합니다.
생성자에 전달한 필드명을 무시하는 사용자 정의 해석기 목록은 다음과 같습니다:
여기서는 기본적으로 DefaultContractResolver에서 파생하고 CreateProperties 메서드를 재정의하는 것이므로 많은 작업이 진행되지는 않습니다. 이 경우 직렬화에서 FieldToIgnore 필드의 이름인 JsonProperty를 생략하고 있습니다. 이제 ClientConfiguration을 다음과 같이 사용하도록 설정하면 됩니다:
그러면 직렬화된 모든 JSON 문서는 FieldToIgnore가 제거됩니다. 저희의 경우 "_id" 필드가 유지되는 것을 원하지 않기 때문에(메타데이터 키가 될 것이므로) 이 필드를 사용했습니다.
확장 메서드를 사용하여 ID 추출 및 JSON 삽입하기
이제 클라이언트를 사용하여 삽입하는 모든 JSON에서 "_id" 필드를 제거하는 컨트랙트 해석기가 있으므로 문서의 ID("_id" 값)를 추출하여 삽입의 키로 사용할 수 있습니다.
Couchbase에서 JSON을 저장하는 데는 두 가지 (주요) 경우가 있습니다(SDK 관점에서). JSON 문서를 나타내는 POCO를 저장하거나 JSON 문서를 동적 타입으로 삽입할 수 있습니다. 각각 특별한 고려가 필요하지만 이를 추상화하는 확장 메서드를 작성하는 것은 매우 쉽습니다:
여기서 동적 타입의 "특별한" 고려 사항은 T가 객체가 되기 때문에 T에 대한 리플렉션에 의존할 수 없다는 것입니다. 먼저 JObject를 생성한 다음 이를 사용하여 "_id" 값을 가져와야 합니다.
이 확장 메서드를 배치한 후에는 다음과 같이 간단한 코드를 작성하여 디스크에서 JSON 파일을 가져오고 키를 추출한 다음 Couchbase에 삽입할 수 있습니다:
POCO의 경우 "Id" 필드를 대상으로 하고 동적의 경우 "_id"를 대상으로 하는데, 이는 동적의 경우 JObject에서 직접 값을 가져오기 때문에 원본 JSON의 대소문자와 규칙이 반영되기 때문입니다.
이제 Couchbase 관리 콘솔에서 JSON 문서를 보면 문서에서 "_id" 필드가 제거되어 키로 사용된 것을 볼 수 있습니다:

소스 가져오기:
이 게시물에 사용한 소스는 다음과 같습니다. 카우치베이스 랩 를 찾아보세요. 프로젝트의 의도(카우치베이스-넷-기고)는 Couchbase SDK로 작업할 때 일반적으로 사용되지만 실제 SDK에 포함되지는 않을 확장 및 플러그인을 제공하기 위한 것입니다. 이 프로젝트는 커뮤니티 주도로 운영되므로 다른 사람들에게 유용할 것이라고 생각되는 기여를 풀 리퀘스트에 자유롭게 보내주세요!