DocumentDB-퀵 가이드
이 장에서는 NoSQL 및 문서 데이터베이스에 대한 주요 개념에 대해 간략하게 설명합니다. 또한 DocumentDB에 대해 간략히 살펴 보겠습니다.
NoSQL 문서 데이터베이스
DocumentDB는 Microsoft의 최신 NoSQL 문서 데이터베이스이므로 NoSQL 문서 데이터베이스라고하면 NoSQL과 문서 데이터베이스가 정확히 무엇을 의미합니까?
SQL은 관계형 데이터베이스의 전통적인 쿼리 언어 인 Structured Query Language를 의미합니다. SQL은 종종 관계형 데이터베이스와 동일합니다.
NoSQL 데이터베이스를 비 관계형 데이터베이스로 생각하는 것이 더 유용하므로 NoSQL은 실제로 비 관계형을 의미합니다.
다음과 같은 키 값 저장소를 포함하는 다양한 유형의 NoSQL 데이터베이스가 있습니다.
- Azure 테이블 저장소.
- Cassandra와 같은 열 기반 저장소.
- NEO4와 같은 그래프 데이터베이스.
- MongoDB 및 Azure DocumentDB와 같은 문서 데이터베이스.
Azure DocumentDB
마이크로 소프트는 공식적 년 4 월 8 일에 푸른 DocumentDB를 시작 일 , 2015 년과는 확실히 일반적인 NoSQL의 문서 데이터베이스로 특징 지어 질 수있다. 대규모 확장이 가능하며 스키마가없는 JSON 문서와 함께 작동합니다.
DocumentDB는 최신 모바일 및 웹 애플리케이션을 위해 설계된 진정한 스키마없는 NoSQL 문서 데이터베이스 서비스입니다.
또한 일관되게 빠른 읽기 및 쓰기, 스키마 유연성 및 필요에 따라 데이터베이스를 쉽게 확장 및 축소 할 수있는 기능을 제공합니다.
인덱싱하는 JSON 문서에 대한 스키마를 가정하거나 요구하지 않습니다.
DocumentDB는 문서가 데이터베이스에 추가되는 즉시 문서의 모든 속성을 자동으로 인덱싱합니다.
DocumentDB는 SQL 언어를 사용하여 복잡한 임시 쿼리를 지원하며 모든 문서는 생성되는 즉시 쿼리 할 수 있으며 문서 계층 내의 모든 속성에서 검색 할 수 있습니다.
DocumentDB – 가격
DocumentDB는 데이터베이스 계정에 포함 된 컬렉션 수를 기준으로 청구됩니다. 각 계정은 하나 이상의 데이터베이스를 가질 수 있으며 각 데이터베이스는 사실상 무제한의 컬렉션을 가질 수 있지만 초기 기본 할당량은 100입니다.이 할당량은 Azure 지원에 문의하여 해제 할 수 있습니다.
컬렉션은 규모의 단위 일뿐만 아니라 비용 단위이기도하므로 DocumentDB에서는 최대 10GB의 스토리지 용량이있는 컬렉션 당 비용을 지불합니다.
최소한 한 달에 약 $ 25의 비용이 드는 데이터베이스에 문서를 저장하려면 하나의 S1 컬렉션이 필요하며 Azure 구독에 대해 요금이 청구됩니다.
데이터베이스의 크기가 커지고 10GB를 초과하면 추가 데이터를 포함하기 위해 다른 컬렉션을 구입해야합니다.
각 S1 컬렉션은 초당 250 개의 요청 단위를 제공하며, 이것이 충분하지 않은 경우 컬렉션을 S2까지 확장하고 한 달에 약 $ 50에 대해 초당 1000 개의 요청 단위를 얻을 수 있습니다.
또한 S3로 전환하여 한 달에 약 $ 100를 지불 할 수도 있습니다.
DocumentDB는 몇 가지 매우 독특한 기능으로 돋보입니다. Azure DocumentDB는 다음과 같은 주요 기능과 이점을 제공합니다.
스키마 없음
관계형 데이터베이스에서 모든 테이블에는 테이블의 각 행이 준수해야하는 열과 데이터 유형을 정의하는 스키마가 있습니다.
반대로 문서 데이터베이스에는 정의 된 스키마가 없으며 모든 문서를 다르게 구성 할 수 있습니다.
SQL 구문
DocumentDB는 SQL 언어를 사용하여 복잡한 임시 쿼리를 가능하게하며, 모든 문서는 생성되는 즉시 즉시 쿼리 할 수 있습니다. 문서 계층 내의 모든 속성을 검색 할 수 있습니다.
조정 가능한 일관성
일관성, 가용성 및 대기 시간 사이에서 적절한 균형을 유지할 수 있도록 세분화되고 잘 정의 된 일관성 수준을 제공합니다.
일관성과 성능 사이에서 최적의 균형을 맞추기 위해 잘 정의 된 4 가지 일관성 수준 중에서 선택할 수 있습니다. 쿼리 및 읽기 작업을 위해 DocumentDB는 네 가지 고유 한 일관성 수준을 제공합니다.
- Strong
- Bounded-staleness
- Session
- Eventual
탄력적 규모
확장 성은 NoSQL을 사용하는 게임의 이름이며 DocumentDB가 제공합니다. DocumentDB는 이미 그 규모가 입증되었습니다.
Office OneNote 및 Xbox와 같은 주요 서비스는 이미 수십 테라 바이트의 JSON 문서가 포함 된 데이터베이스, 백만 명 이상의 활성 사용자 및 99.95 % 가용성으로 일관되게 작동하는 데이터베이스를 통해 DocumentDB의 지원을받습니다.
애플리케이션이 성장함에 따라 더 많은 단위를 생성하여 예측 가능한 성능으로 DocumentDB를 탄력적으로 확장 할 수 있습니다.
완전 관리
DocumentDB는 Azure에서 실행되는 서비스로서의 완전 관리 형 클라우드 기반 플랫폼으로 제공됩니다.
단순히 설치하거나 관리 할 것이 없습니다.
처리 할 서버, 케이블, 운영 체제 또는 업데이트, 설정할 복제본이 없습니다.
Microsoft는 모든 작업을 수행하고 서비스를 계속 실행합니다.
말 그대로 몇 분 안에 브라우저와 Azure 구독을 사용하여 DocumentDB 작업을 시작할 수 있습니다.
Microsoft는 SQL Server가 포함 된 무료 버전의 Visual Studio를 제공하며 다음에서 다운로드 할 수 있습니다. https://www.visualstudio.com
설치
Step 1− 다운로드가 완료되면 설치 프로그램을 실행하십시오. 다음 대화 상자가 표시됩니다.
Step 2 − 설치 버튼을 클릭하면 설치 과정이 시작됩니다.
Step 3 − 설치 과정이 성공적으로 완료되면 다음 대화 상자가 나타납니다.
Step 4 −이 대화 상자를 닫고 필요한 경우 컴퓨터를 다시 시작하십시오.
Step 5− 이제 시작 메뉴에서 Visual Studio를 열면 아래 대화 상자가 열립니다. 준비를 위해서만 처음으로 시간이 걸릴 것입니다.
모든 작업이 완료되면 Visual Studio의 기본 창이 표시됩니다.
Step 6 − 파일 → 새로 만들기 → 프로젝트에서 새 프로젝트를 생성 해 보겠습니다.
Step 7 − 콘솔 응용 프로그램을 선택하고 이름 필드에 DocumentDBDemo를 입력 한 후 확인 버튼을 클릭합니다.
Step 8 − 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭합니다.
Step 9 − NuGet 패키지 관리를 선택하면 Visual Studio에서 다음 창이 열리고 온라인 검색 입력 상자에서 DocumentDB 클라이언트 라이브러리를 검색합니다.
Step 10 − 설치 버튼을 클릭하여 최신 버전을 설치합니다.
Step 11− "동의 함"을 클릭합니다. 설치가 완료되면 출력 창에 메시지가 표시됩니다.
이제 애플리케이션을 시작할 준비가되었습니다.
Microsoft Azure DocumentDB를 사용하려면 DocumentDB 계정을 만들어야합니다. 이 장에서는 Azure Portal을 사용하여 DocumentDB 계정을 만듭니다.
Step 1 − 온라인에 로그인 https://portal.azure.com 이미 Azure 구독이있는 경우 그렇지 않으면 먼저 로그인해야합니다.
메인 대시 보드가 표시됩니다. 완벽하게 사용자 정의 할 수 있으므로 원하는 방식으로 타일을 정렬하고 크기를 조정하고 자주 사용하거나 더 이상 수행하지 않는 타일을 추가 및 제거 할 수 있습니다.
Step 2 − 페이지 왼쪽 상단의 '새로 만들기'옵션을 선택합니다.
Step 3 − 이제 데이터 + 저장소> Azure DocumentDB 옵션을 선택하면 다음 새 DocumentDB 계정 섹션이 표시됩니다.
.documents.azure.com과 결합 된 글로벌 고유 이름 (ID)을 만들어야합니다. 이는 DocumentDB 계정에 대해 공개적으로 주소를 지정할 수있는 끝점입니다. 해당 계정 아래에 생성 된 모든 데이터베이스는이 끝점을 사용하여 인터넷을 통해 액세스 할 수 있습니다.
Step 4 − 이름을 azuredocdbdemo로 지정하고 리소스 그룹 → new_resource를 클릭합니다.
Step 5− 위치, 즉이 계정을 호스팅 할 Microsoft 데이터 센터를 선택합니다. 위치를 선택하고 지역을 선택하십시오.
Step 6 − 대시 보드에 고정 확인란을 선택하고 생성 버튼을 클릭합니다.
타일이 이미 대시 보드에 추가되어 계정이 생성되고 있음을 알 수 있습니다. DocumentDB가 엔드 포인트를 할당하고, 복제본을 프로비저닝하고, 백그라운드에서 다른 작업을 수행하는 동안 새 계정에 대해 설정하는 데 실제로 몇 분 정도 걸릴 수 있습니다.
완료되면 대시 보드가 표시됩니다.
Step 7 − 이제 생성 된 DocumentDB 계정을 클릭하면 다음 이미지와 같은 상세 화면이 나타납니다.
DocumentDB에 대한 프로그래밍을 시작할 때 첫 번째 단계는 연결하는 것입니다. 따라서 DocumentDB 계정에 연결하려면 두 가지가 필요합니다.
- Endpoint
- 인증 키
끝점
Endpoint는 DocumentDB 계정의 URL이며 DocumentDB 계정 이름을 .documents.azure.com과 결합하여 구성됩니다. 대시 보드로 이동하겠습니다.
이제 생성 된 DocumentDB 계정을 클릭합니다. 다음 이미지와 같이 세부 정보가 표시됩니다.
'키'옵션을 선택하면 다음 이미지와 같이 추가 정보가 표시됩니다. 끝점으로 사용할 수있는 DocumentDB 계정의 URL도 표시됩니다.
인증 키
인증 키에는 자격 증명이 포함되며 두 가지 유형의 키가 있습니다. 마스터 키는 계정 내의 모든 리소스에 대한 전체 액세스를 허용하는 반면 리소스 토큰은 특정 리소스에 대한 제한된 액세스를 허용합니다.
마스터 키
마스터 키로 할 수없는 것은 없습니다. 원하는 경우 마스터 키를 사용하여 전체 데이터베이스를 날려 버릴 수 있습니다.
따라서 마스터 키를 공유하거나 클라이언트 환경에 배포하고 싶지는 않습니다. 추가 보안 조치로 자주 변경하는 것이 좋습니다.
실제로 각 데이터베이스 계정에는 위의 스크린 샷에서 강조 표시된대로 기본 및 보조의 두 개의 마스터 키가 있습니다.
자원 토큰
마스터 키 대신 리소스 토큰을 사용할 수도 있습니다.
리소스 토큰을 기반으로하는 연결은 토큰으로 지정된 리소스에만 액세스 할 수 있으며 다른 리소스에는 액세스 할 수 없습니다.
리소스 토큰은 사용자 권한을 기반으로하므로 먼저 사용자를 한 명 이상 생성하면 데이터베이스 수준에서 정의됩니다.
각 사용자가 액세스 할 수 있도록 허용 할 리소스에 따라 각 사용자에 대해 하나 이상의 권한을 만듭니다.
각 권한은 주어진 리소스에 대한 읽기 전용 또는 전체 액세스를 허용하고 데이터베이스 내의 모든 사용자 리소스가 될 수있는 리소스 토큰을 생성합니다.
3 장에서 만든 콘솔 응용 프로그램으로 이동하겠습니다.
Step 1 − Program.cs 파일에 다음 참조를 추가합니다.
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
Step 2− 이제 끝점 URL과 인증 키를 추가합니다. 이 예에서는 기본 키를 인증 키로 사용합니다.
귀하의 경우 엔드 포인트 URL과 인증 키는 모두 달라야합니다.
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey =
"BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
Step 3 − CreateDocumentClient라는 비동기 작업에서 DocumentClient의 새 인스턴스를 만들고 새 DocumentClient를 인스턴스화합니다.
Step 4 − Main 메서드에서 비동기 작업을 호출합니다.
다음은 지금까지의 완전한 Program.cs 파일입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
}
}
}
이 장에서는 DocumentDB 계정에 연결하고 DocumentClient 클래스의 인스턴스를 만드는 방법을 배웠습니다.
이 장에서는 데이터베이스를 만드는 방법을 배웁니다. Microsoft Azure DocumentDB를 사용하려면 DocumentDB 계정, 데이터베이스, 컬렉션 및 문서가 있어야합니다. 이미 DocumentDB 계정이 있습니다. 이제 데이터베이스를 만들려면 두 가지 옵션이 있습니다.
- Microsoft Azure 포털 또는
- .Net SDK
Microsoft Azure Portal을 사용하여 DocumentDB 용 데이터베이스 만들기
포털을 사용하여 데이터베이스를 생성하는 단계는 다음과 같습니다.
Step 1 − Azure Portal에 로그인하면 대시 보드가 표시됩니다.
Step 2 − 이제 생성 된 DocumentDB 계정을 클릭하면 다음 스크린 샷과 같은 세부 정보가 표시됩니다.
Step 3 − 데이터베이스 추가 옵션을 선택하고 데이터베이스의 ID를 제공하십시오.
Step 4 − 확인을 클릭합니다.
데이터베이스가 추가 된 것을 볼 수 있습니다. 현재는 컬렉션이 없지만 나중에 JSON 문서를 저장할 컨테이너 인 컬렉션을 추가 할 수 있습니다. ID와 리소스 ID가 모두 있습니다.
.Net SDK를 사용하여 DocumentDB 용 데이터베이스 만들기
.Net SDK를 사용하여 데이터베이스를 생성하려면 다음 단계를 따르십시오.
Step 1 − 마지막 장에서 Visual Studio에서 콘솔 응용 프로그램을 엽니 다.
Step 2− 새로운 데이터베이스 개체를 생성하여 새로운 데이터베이스를 생성합니다. 새 데이터베이스를 만들려면 CreateDatabase 작업에서 "mynewdb"로 설정하는 Id 속성 만 할당하면됩니다.
private async static Task CreateDatabase(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("******** Create Database *******");
var databaseDefinition = new Database { Id = "mynewdb" };
var result = await client.CreateDatabaseAsync(databaseDefinition);
var database = result.Resource;
Console.WriteLine(" Database Id: {0}; Rid: {1}", database.Id, database.ResourceId);
Console.WriteLine("******** Database Created *******");
}
Step 3− 이제이 databaseDefinition을 CreateDatabaseAsync에 전달하고 Resource 속성으로 결과를 반환합니다. 모든 create object 메서드는 생성 된 항목을 설명하는 Resource 속성 (이 경우 데이터베이스)을 반환합니다.
Resource 속성에서 새 데이터베이스 개체를 가져 오면 DocumentDB가 할당 한 리소스 ID와 함께 콘솔에 표시됩니다.
Step 4 − 이제 DocumentClient를 인스턴스화 한 후 CreateDocumentClient 작업에서 CreateDatabase 작업을 호출합니다.
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await CreateDatabase(client);
}
다음은 지금까지의 완전한 Program.cs 파일입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await CreateDatabase(client);
}
}
private async static Task CreateDatabase(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("******** Create Database *******");
var databaseDefinition = new Database { Id = "mynewdb" };
var result = await client.CreateDatabaseAsync(databaseDefinition);
var database = result.Resource;
Console.WriteLine(" Database Id: {0}; Rid: {1}", database.Id, database.ResourceId);
Console.WriteLine("******** Database Created *******");
}
}
}
위의 코드가 컴파일되고 실행되면 데이터베이스 및 리소스 ID가 포함 된 다음 출력이 표시됩니다.
******** Create Database *******
Database Id: mynewdb; Rid: ltpJAA==
******** Database Created *******
지금까지 DocumentDB 계정에 두 개의 데이터베이스를 만들었습니다. 첫 번째 데이터베이스는 Azure Portal을 사용하여 만들고 두 번째 데이터베이스는 .Net SDK를 사용하여 만듭니다. 이제 이러한 데이터베이스를 보려면 Azure Portal을 사용할 수 있습니다.
Azure Portal에서 DocumentDB 계정으로 이동하면 이제 두 개의 데이터베이스가 표시됩니다.
.Net SDK를 사용하여 코드에서 데이터베이스를 보거나 나열 할 수도 있습니다. 다음은 관련된 단계입니다.
Step 1 − 전체 목록을 반환하는 매개 변수없이 데이터베이스 쿼리를 발행하지만 특정 데이터베이스 또는 특정 데이터베이스를 찾기 위해 쿼리를 전달할 수도 있습니다.
private static void GetDatabases(DocumentClient client) {
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("******** Get Databases List ********");
var databases = client.CreateDatabaseQuery().ToList();
foreach (var database in databases) {
Console.WriteLine(" Database Id: {0}; Rid: {1}", database.Id, database.ResourceId);
}
Console.WriteLine();
Console.WriteLine("Total databases: {0}", databases.Count);
}
컬렉션, 문서, 사용자 및 기타 리소스를 찾기위한 이러한 CreateQuery 메서드가 많이 있음을 알 수 있습니다. 이러한 메서드는 실제로 쿼리를 실행하지 않고 쿼리를 정의하고 반복 가능한 개체를 반환합니다.
실제로 쿼리를 실행하고 결과를 반복하며 목록으로 반환하는 것은 ToList ()에 대한 호출입니다.
Step 2 − DocumentClient가 인스턴스화 된 후 CreateDocumentClient 작업에서 GetDatabases 메서드를 호출합니다.
Step 3 − 또한 CreateDatabase 작업에 주석을 달거나 데이터베이스 ID를 변경해야합니다. 그렇지 않으면 데이터베이스가 존재한다는 오류 메시지가 표시됩니다.
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
//await CreateDatabase(client);
GetDatabases(client);
}
다음은 지금까지의 완전한 Program.cs 파일입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await CreateDatabase(client);
GetDatabases(client);
}
}
private async static Task CreateDatabase(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("******** Create Database *******");
var databaseDefinition = new Database { Id = "mynewdb" };
var result = await client.CreateDatabaseAsync(databaseDefinition);
var database = result.Resource;
Console.WriteLine(" Database Id: {0}; Rid: {1}", database.Id, database.ResourceId);
Console.WriteLine("******** Database Created *******");
}
private static void GetDatabases(DocumentClient client) {
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("******** Get Databases List ********");
var databases = client.CreateDatabaseQuery().ToList();
foreach (var database in databases) {
Console.WriteLine(" Database Id: {0}; Rid: {1}",
database.Id, database.ResourceId);
}
Console.WriteLine();
Console.WriteLine("Total databases: {0}", databases.Count);
}
}
}
위의 코드가 컴파일되고 실행되면 두 데이터베이스의 데이터베이스 및 리소스 ID가 포함 된 다음 출력이 표시됩니다. 결국 총 데이터베이스 수도 표시됩니다.
******** Get Databases List ********
Database Id: myfirstdb; Rid: Ic8LAA==
Database Id: mynewdb; Rid: ltpJAA==
Total databases: 2
.Net SDK를 사용하여 코드뿐만 아니라 포털에서 데이터베이스를 삭제할 수 있습니다. 여기서는 DocumentDB에서 데이터베이스를 삭제하는 방법을 단계별로 설명합니다.
Step 1− Azure Portal에서 DocumentDB 계정으로 이동합니다. 데모를 위해 다음 스크린 샷과 같이 데이터베이스를 두 개 더 추가했습니다.
Step 2− 데이터베이스를 삭제하려면 해당 데이터베이스를 클릭해야합니다. tempdb를 선택하면 다음 페이지가 표시되고 '데이터베이스 삭제'옵션을 선택합니다.
Step 3 − 확인 메시지가 표시되면 '예'버튼을 클릭합니다.
대시 보드에서 tempdb를 더 이상 사용할 수 없음을 알 수 있습니다.
.Net SDK를 사용하여 코드에서 데이터베이스를 삭제할 수도 있습니다. 다음은 단계입니다.
Step 1 − 삭제할 데이터베이스의 ID를 지정하여 데이터베이스를 삭제하겠습니다.하지만 SelfLink가 필요합니다.
Step 2 − 이전과 같이 CreateDatabaseQuery를 호출하고 있지만 이번에는 실제로 tempdb1이라는 ID를 가진 하나의 데이터베이스 만 반환하는 쿼리를 제공합니다.
private async static Task DeleteDatabase(DocumentClient client) {
Console.WriteLine("******** Delete Database ********");
Database database = client
.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'tempdb1'")
.AsEnumerable()
.First();
await client.DeleteDatabaseAsync(database.SelfLink);
}
Step 3− 이번에는 실제로 목록 객체가 필요하지 않기 때문에 ToList () 대신 AsEnumerable을 호출 할 수 있습니다. 결과 만 예상하고 AsEnumerable을 호출하면 First ()를 사용하여 쿼리에서 반환 된 첫 번째 데이터베이스 개체를 가져올 수 있습니다. 이것은 tempdb1의 데이터베이스 개체이며 데이터베이스를 삭제하는 DeleteDatabaseAsync를 호출하는 데 사용할 수있는 SelfLink가 있습니다.
Step 4 − 또한 DocumentClient를 인스턴스화 한 후 CreateDocumentClient 작업에서 DeleteDatabase 작업을 호출해야합니다.
Step 5 − 지정된 데이터베이스를 삭제 한 후 데이터베이스 목록을 보려면 GetDatabases 메서드를 다시 호출 해 보겠습니다.
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
//await CreateDatabase(client);
GetDatabases(client);
await DeleteDatabase(client);
GetDatabases(client);
}
다음은 지금까지의 완전한 Program.cs 파일입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
//await CreateDatabase(client);
GetDatabases(client);
await DeleteDatabase(client);
GetDatabases(client);
}
}
private async static Task CreateDatabase(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("******** Create Database *******");
var databaseDefinition = new Database { Id = "mynewdb" };
var result = await client.CreateDatabaseAsync(databaseDefinition);
var database = result.Resource;
Console.WriteLine(" Database Id: {0}; Rid: {1}",
database.Id, database.ResourceId);
Console.WriteLine("******** Database Created *******");
}
private static void GetDatabases(DocumentClient client) {
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("******** Get Databases List ********");
var databases = client.CreateDatabaseQuery().ToList();
foreach (var database in databases) {
Console.WriteLine(" Database Id: {0}; Rid: {1}", database.Id,
database.ResourceId);
}
Console.WriteLine();
Console.WriteLine("Total databases: {0}", databases.Count);
}
private async static Task DeleteDatabase(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("******** Delete Database ********");
Database database = client
.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'tempdb1'")
.AsEnumerable()
.First();
await client.DeleteDatabaseAsync(database.SelfLink);
}
}
}
위의 코드가 컴파일되고 실행되면 세 데이터베이스의 데이터베이스 및 리소스 ID와 총 데이터베이스 수를 포함하는 다음 출력이 표시됩니다.
******** Get Databases List ********
Database Id: myfirstdb; Rid: Ic8LAA==
Database Id: mynewdb; Rid: ltpJAA==
Database Id: tempdb1; Rid: 06JjAA==
Total databases: 3
******** Delete Database ********
******** Get Databases List ********
Database Id: myfirstdb; Rid: Ic8LAA==
Database Id: mynewdb; Rid: ltpJAA==
Total databases: 2
데이터베이스를 삭제하면 마지막에 DocumentDB 계정에 두 개의 데이터베이스 만 남는 것을 볼 수 있습니다.
이 장에서는 컬렉션을 만드는 방법을 배웁니다. 데이터베이스를 만드는 것과 비슷합니다. 포털 또는 .Net SDK를 사용하는 코드에서 컬렉션을 만들 수 있습니다.
Step 1 − Azure Portal의 기본 대시 보드로 이동합니다.
Step 2 − 데이터베이스 목록에서 myfirstdb를 선택합니다.
Step 3− '컬렉션 추가'옵션을 클릭하고 컬렉션 ID를 지정합니다. 다른 옵션에 대한 가격 등급을 선택합니다.
Step 4 − S1 Standard를 선택하고 선택 → 확인 버튼을 클릭합니다.
MyCollection이 myfirstdb에 추가 된 것을 볼 수 있습니다.
.Net SDK를 사용하여 코드에서 컬렉션을 만들 수도 있습니다. 코드에서 컬렉션을 추가하는 다음 단계를 살펴 보겠습니다.
Step 1 − Visual Studio에서 콘솔 애플리케이션을 엽니 다.
Step 2 − 컬렉션을 생성하려면 먼저 CreateDocumentClient 작업에서 ID로 myfirstdb 데이터베이스를 검색합니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
await CreateCollection(client, "MyCollection1");
await CreateCollection(client, "MyCollection2", "S2");
}
}
다음은 CreateCollection 작업에 대한 구현입니다.
private async static Task CreateCollection(DocumentClient client, string collectionId,
string offerType = "S1") {
Console.WriteLine();
Console.WriteLine("**** Create Collection {0} in {1} ****", collectionId, database.Id);
var collectionDefinition = new DocumentCollection { Id = collectionId };
var options = new RequestOptions { OfferType = offerType };
var result = await client.CreateDocumentCollectionAsync(database.SelfLink,
collectionDefinition, options);
var collection = result.Resource;
Console.WriteLine("Created new collection");
ViewCollection(collection);
}
여기서는 offerType을 호출하는 새 컬렉션의 성능 계층을 설정하는 데 사용하는 옵션 매개 변수도 허용하는 CreateDocumentCollectionAsync 메서드에 대해 원하는 Id를 사용하여 새 컬렉션을 정의하는 새 DocumentCollection 개체를 만듭니다.
기본값은 S1이며, MyCollection1의 경우 offerType을 전달하지 않았으므로 S1 컬렉션이되고 MyCollection2의 경우 S2를 전달하여 위에 표시된대로 S2가됩니다.
다음은 ViewCollection 메서드의 구현입니다.
private static void ViewCollection(DocumentCollection collection) {
Console.WriteLine("Collection ID: {0} ", collection.Id);
Console.WriteLine("Resource ID: {0} ", collection.ResourceId);
Console.WriteLine("Self Link: {0} ", collection.SelfLink);
Console.WriteLine("Documents Link: {0} ", collection.DocumentsLink);
Console.WriteLine("UDFs Link: {0} ", collection.UserDefinedFunctionsLink);
Console.WriteLine(" StoredProcs Link: {0} ", collection.StoredProceduresLink);
Console.WriteLine("Triggers Link: {0} ", collection.TriggersLink);
Console.WriteLine("Timestamp: {0} ", collection.Timestamp);
}
다음은 컬렉션에 대한 program.cs 파일의 전체 구현입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
private static Database database;
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
await CreateCollection(client, "MyCollection1");
await CreateCollection(client, "MyCollection2", "S2");
//await CreateDatabase(client);
//GetDatabases(client);
//await DeleteDatabase(client);
//GetDatabases(client);
}
}
private async static Task CreateCollection(DocumentClient client,
string collectionId, string offerType = "S1") {
Console.WriteLine();
Console.WriteLine("**** Create Collection {0} in {1} ****", collectionId,
database.Id);
var collectionDefinition = new DocumentCollection { Id = collectionId };
var options = new RequestOptions { OfferType = offerType };
var result = await
client.CreateDocumentCollectionAsync(database.SelfLink,
collectionDefinition, options);
var collection = result.Resource;
Console.WriteLine("Created new collection");
ViewCollection(collection);
}
private static void ViewCollection(DocumentCollection collection) {
Console.WriteLine("Collection ID: {0} ", collection.Id);
Console.WriteLine("Resource ID: {0} ", collection.ResourceId);
Console.WriteLine("Self Link: {0} ", collection.SelfLink);
Console.WriteLine("Documents Link: {0} ", collection.DocumentsLink);
Console.WriteLine("UDFs Link: {0} ", collection.UserDefinedFunctionsLink);
Console.WriteLine("StoredProcs Link: {0} ", collection.StoredProceduresLink);
Console.WriteLine("Triggers Link: {0} ", collection.TriggersLink);
Console.WriteLine("Timestamp: {0} ", collection.Timestamp);
}
}
}
위의 코드가 컴파일되고 실행되면 컬렉션과 관련된 모든 정보가 포함 된 다음과 같은 출력이 표시됩니다.
**** Create Collection MyCollection1 in myfirstdb ****
Created new collection
Collection ID: MyCollection1
Resource ID: Ic8LAPPvnAA=
Self Link: dbs/Ic8LAA==/colls/Ic8LAPPvnAA=/
Documents Link: dbs/Ic8LAA==/colls/Ic8LAPPvnAA=/docs/
UDFs Link: dbs/Ic8LAA==/colls/Ic8LAPPvnAA=/udfs/
StoredProcs Link: dbs/Ic8LAA==/colls/Ic8LAPPvnAA=/sprocs/
Triggers Link: dbs/Ic8LAA==/colls/Ic8LAPPvnAA=/triggers/
Timestamp: 12/10/2015 4:55:36 PM
**** Create Collection MyCollection2 in myfirstdb ****
Created new collection
Collection ID: MyCollection2
Resource ID: Ic8LAKGHDwE=
Self Link: dbs/Ic8LAA==/colls/Ic8LAKGHDwE=/
Documents Link: dbs/Ic8LAA==/colls/Ic8LAKGHDwE=/docs/
UDFs Link: dbs/Ic8LAA==/colls/Ic8LAKGHDwE=/udfs/
StoredProcs Link: dbs/Ic8LAA==/colls/Ic8LAKGHDwE=/sprocs/
Triggers Link: dbs/Ic8LAA==/colls/Ic8LAKGHDwE=/triggers/
Timestamp: 12/10/2015 4:55:38 PM
컬렉션 또는 컬렉션을 삭제하려면 .Net SDK를 사용하여 코드뿐만 아니라 포털에서도 동일한 작업을 수행 할 수 있습니다.
Step 1− Azure Portal에서 DocumentDB 계정으로 이동합니다. 데모를 위해 다음 스크린 샷과 같이 컬렉션을 두 개 더 추가했습니다.
Step 2− 컬렉션을 삭제하려면 해당 컬렉션을 클릭해야합니다. TempCollection1을 선택하겠습니다. 다음 페이지가 표시되면 '컬렉션 삭제'옵션을 선택합니다.
Step 3− 확인 메시지가 표시됩니다. 이제 '예'버튼을 클릭하십시오.
대시 보드에서 TempCollection1을 더 이상 사용할 수 없음을 알 수 있습니다.
.Net SDK를 사용하여 코드에서 컬렉션을 삭제할 수도 있습니다. 이를 위해 다음 단계는 다음과 같습니다.
Step 1 − 삭제할 컬렉션의 ID를 지정하여 컬렉션을 삭제하겠습니다.
리소스를 삭제하는 데 필요한 selfLink를 얻기 위해 Id가 쿼리하는 일반적인 패턴입니다.
private async static Task DeleteCollection(DocumentClient client, string collectionId) {
Console.WriteLine();
Console.WriteLine("**** Delete Collection {0} in {1} ****", collectionId, database.Id);
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id",
Parameters = new SqlParameterCollection {
new SqlParameter {
Name = "@id", Value = collectionId
}
}
};
DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink,
query).AsEnumerable().First();
await client.DeleteDocumentCollectionAsync(collection.SelfLink);
Console.WriteLine("Deleted collection {0} from database {1}", collectionId,
database.Id);
}
여기에서는 매개 변수화 된 쿼리를 생성하는 선호하는 방법을 볼 수 있습니다. collectionId를 하드 코딩하지 않으므로이 메서드를 사용하여 컬렉션을 삭제할 수 있습니다. 이 SqlQuerySpec의 매개 변수 속성에 할당 된이 SqlParameterCollection에 Id 매개 변수가 정의되어있는 Id별로 특정 컬렉션을 쿼리합니다.
그런 다음 SDK는 내부에 collectionId가 포함 된 DocumentDB에 대한 최종 쿼리 문자열을 구성하는 작업을 수행합니다.
Step 2 − 쿼리를 실행 한 다음 자체 링크를 사용하여 CreateDocumentClient 작업에서 컬렉션을 삭제합니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
await DeleteCollection(client, "TempCollection");
}
}
다음은 Program.cs 파일의 전체 구현입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
namespace DocumentDBDemo {
class Program {
private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/";
private const string AuthorizationKey = "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/
StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";
private static Database database;
static void Main(string[] args) {
try {
CreateDocumentClient().Wait();
} catch (Exception e) {
Exception baseException = e.GetBaseException();
Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
}
Console.ReadKey();
}
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
await DeleteCollection(client, "TempCollection");
//await CreateCollection(client, "MyCollection1");
//await CreateCollection(client, "MyCollection2", "S2");
////await CreateDatabase(client);
//GetDatabases(client);
//await DeleteDatabase(client);
//GetDatabases(client);
}
}
private async static Task CreateCollection(DocumentClient client,
string collectionId, string offerType = "S1") {
Console.WriteLine();
Console.WriteLine("**** Create Collection {0} in {1} ****", collectionId,
database.Id);
var collectionDefinition = new DocumentCollection { Id = collectionId };
var options = new RequestOptions { OfferType = offerType };
var result = await client.CreateDocumentCollectionAsync(database.SelfLink,
collectionDefinition, options);
var collection = result.Resource;
Console.WriteLine("Created new collection");
ViewCollection(collection);
}
private static void ViewCollection(DocumentCollection collection) {
Console.WriteLine("Collection ID: {0} ", collection.Id);
Console.WriteLine("Resource ID: {0} ", collection.ResourceId);
Console.WriteLine("Self Link: {0} ", collection.SelfLink);
Console.WriteLine("Documents Link: {0} ", collection.DocumentsLink);
Console.WriteLine("UDFs Link: {0} ", collection.UserDefinedFunctionsLink);
Console.WriteLine("StoredProcs Link: {0} ", collection.StoredProceduresLink);
Console.WriteLine("Triggers Link: {0} ", collection.TriggersLink);
Console.WriteLine("Timestamp: {0} ", collection.Timestamp);
}
private async static Task DeleteCollection(DocumentClient client,
string collectionId) {
Console.WriteLine();
Console.WriteLine("**** Delete Collection {0} in {1} ****", collectionId,
database.Id);
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id", Parameters = new
SqlParameterCollection {
new SqlParameter {
Name = "@id", Value = collectionId
}
}
};
DocumentCollection collection = client.CreateDocumentCollectionQuery
(database.SelfLink, query).AsEnumerable().First();
await client.DeleteDocumentCollectionAsync(collection.SelfLink);
Console.WriteLine("Deleted collection {0} from database {1}", collectionId,
database.Id);
}
}
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Delete Collection TempCollection in myfirstdb ****
Deleted collection TempCollection from database myfirstdb
이 장에서는 컬렉션의 실제 문서 작업에 대해 알아 봅니다. Azure Portal 또는 .Net SDK를 사용하여 문서를 만들 수 있습니다.
Azure Portal을 사용하여 문서 만들기
컬렉션에 문서를 추가하기 위해 다음 단계를 살펴 보겠습니다.
Step 1 − myfirstdb에 S1 가격 책정 계층의 새 컬렉션 Families를 추가합니다.
Step 2 − Families 컬렉션을 선택하고 문서 만들기 옵션을 클릭하여 새 문서 블레이드를 엽니 다.
새 문서에 대한 JSON을 입력 할 수있는 간단한 텍스트 편집기입니다.
Step 3 − 이것은 원시 데이터 입력이므로 첫 번째 문서를 입력하겠습니다.
{
"id": "AndersenFamily",
"lastName": "Andersen",
"parents": [
{ "firstName": "Thomas", "relationship": "father" },
{ "firstName": "Mary Kay", "relationship": "mother" }
],
"children": [
{
"firstName": "Henriette Thaulow",
"gender": "female",
"grade": 5,
"pets": [ { "givenName": "Fluffy", "type": "Rabbit" } ]
}
],
"location": { "state": "WA", "county": "King", "city": "Seattle"},
"isRegistered": true
}
위 문서를 입력하면 다음과 같은 화면이 나옵니다.
문서의 ID를 제공했습니다. id 값은 항상 필수이며 동일한 컬렉션의 다른 모든 문서에서 고유해야합니다. 생략하면 DocumentDB는 GUID 또는 전역 고유 식별자를 사용하여 자동으로 생성합니다.
ID는 항상 문자열이며 숫자, 날짜, 부울 또는 다른 개체가 될 수 없으며 255자를 초과 할 수 없습니다.
또한 필수 id, lastName 및 isRegistered와 같은 몇 가지 최상위 속성이 있지만 중첩 속성도있는 문서의 계층 구조를 확인하십시오.
예를 들어 parent 속성은 대괄호로 표시된 JSON 배열로 제공됩니다. 이 예제에서는 배열에 자식이 하나만 있더라도 자식을위한 또 다른 배열도 있습니다.
Step 4 − '저장'버튼을 클릭하여 문서를 저장하고 첫 번째 문서를 생성했습니다.
보시다시피 예쁜 형식이 JSON에 적용되어 각 속성의 중첩 수준을 전달하기 위해 공백으로 들여 쓰기 된 자체 줄에서 모든 속성을 나눕니다.
포털에는 문서 탐색기가 포함되어 있으므로 방금 만든 문서를 검색하는 데 사용하겠습니다.
Step 5− 해당 컬렉션의 문서를 보려면 데이터베이스와 데이터베이스 내의 컬렉션을 선택합니다. 현재는 myfirstdb라는 이름의 데이터베이스 하나와 Families라는 컬렉션이 있으며 둘 다 여기 드롭 다운에서 미리 선택되어 있습니다.
기본적으로 문서 탐색기는 컬렉션 내에서 필터링되지 않은 문서 목록을 표시하지만 ID로 특정 문서를 검색하거나 부분 ID의 와일드 카드 검색을 기반으로 여러 문서를 검색 할 수도 있습니다.
지금까지 컬렉션에는 문서가 하나만 있으며 다음 화면 인 AndersonFamily에 해당 ID가 표시됩니다.
Step 6 − 문서를 보려면 ID를 클릭하십시오.
.NET SDK로 문서 생성
문서는 다른 유형의 리소스 일 뿐이며 SDK를 사용하여 리소스를 처리하는 방법에 이미 익숙해졌습니다.
문서와 다른 리소스의 가장 큰 차이점은 스키마가 없다는 것입니다.
따라서 많은 옵션이 있습니다. 당연히 JSON 개체 그래프 또는 JSON 텍스트의 원시 문자열로 작업 할 수 있지만 컴파일 타임에 클래스를 정의하지 않고도 런타임에 속성에 바인딩 할 수있는 동적 개체를 사용할 수도 있습니다.
실제 C # 개체 또는 호출 된 엔터티 (비즈니스 도메인 클래스 일 수 있음)로 작업 할 수도 있습니다.
.Net SDK를 사용하여 문서 작성을 시작하겠습니다. 다음은 단계입니다.
Step 1 − DocumentClient를 인스턴스화 한 다음 myfirstdb 데이터베이스를 쿼리 한 다음 MyCollection 컬렉션을 쿼리합니다. MyCollection 컬렉션은이 개인 변수 컬렉션에 저장되어 클래스 전체에서 액세스 할 수 있습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
await CreateDocuments(client);
}
}
Step 2 − CreateDocuments 작업에서 일부 문서를 생성합니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
}, postalCode = "11229", countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
}
첫 번째 문서는이 동적 개체에서 생성됩니다. 이것은 JSON처럼 보일 수 있지만 물론 그렇지 않습니다. 이것은 C # 코드이며 실제 .NET 개체를 생성하고 있지만 클래스 정의는 없습니다. 대신 객체가 초기화되는 방식에서 속성이 유추됩니다.
이 문서에 대해 Id 속성을 제공하지 않았습니다.
이제 CreateDocument를 살펴 보겠습니다. 데이터베이스와 컬렉션을 만들 때 본 것과 같은 패턴입니다.
private async static Task<Document> CreateDocument(DocumentClient client,
object documentObject) {
var result = await client.CreateDocumentAsync(collection.SelfLink, documentObject);
var document = result.Resource;
Console.WriteLine("Created new document: {0}\r\n{1}", document.Id, document);
return result;
}
Step 3− 이번에는 문서를 추가 할 컬렉션의 SelfLink를 지정하는 CreateDocumentAsync를 호출합니다. 이 경우 시스템 생성 속성이있는 새 문서를 나타내는 리소스 속성이있는 응답을 반환합니다.
Document 개체는 리소스에서 상속되는 SDK의 정의 된 클래스이므로 모든 공통 리소스 속성이 있지만 스키마가없는 문서 자체를 정의하는 동적 속성도 포함합니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
}, postalCode = "11229", countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Create Documents ****
Created new document: 34e9873a-94c8-4720-9146-d63fb7840fad {
"name": "New Customer 1",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn", "stateProvinceName": "New York"
},
"postalCode": "11229", "countryRegionName": "United States"
},
"id": "34e9873a-94c8-4720-9146-d63fb7840fad",
"_rid": "Ic8LAMEUVgACAAAAAAAAAA==",
"_ts": 1449812756,
"_self": "dbs/Ic8LAA==/colls/Ic8LAMEUVgA=/docs/Ic8LAMEUVgACAAAAAAAAAA==/",
"_etag": "\"00001000-0000-0000-0000-566a63140000\"",
"_attachments": "attachments/"
}
Created document 34e9873a-94c8-4720-9146-d63fb7840fad from dynamic object
보시다시피, 우리는 Id를 제공하지 않았지만 DocumentDB는 새 문서를 위해 이것을 생성했습니다.
DocumentDB에서는 실제로 SQL을 사용하여 문서를 쿼리하므로이 장에서는 DocumentDB의 특수 SQL 구문을 사용하여 쿼리하는 방법에 대해 설명합니다. .NET 개발을 수행하는 경우에도 사용할 수 있고 LINQ 쿼리에서 적절한 SQL을 생성 할 수있는 LINQ 공급자도 있습니다.
포털을 사용하여 문서 쿼리
Azure Portal에는 DocumentDB 데이터베이스에 대해 SQL 쿼리를 실행할 수있는 쿼리 탐색기가 있습니다.
쿼리 탐색기를 사용하여 가능한 가장 간단한 쿼리로 시작하는 쿼리 언어의 다양한 기능과 기능을 보여줄 것입니다.
Step 1 − 데이터베이스 블레이드에서 클릭하여 쿼리 탐색기 블레이드를 엽니 다.
쿼리는 컬렉션 범위 내에서 실행되므로 쿼리 탐색기를 사용하여이 드롭 다운에서 컬렉션을 선택할 수 있습니다.
Step 2 − 포털을 사용하여 이전에 생성 한 Families 컬렉션을 선택합니다.
쿼리 탐색기는이 간단한 쿼리 SELECT * FROM c로 열립니다.이 쿼리는 컬렉션에서 모든 문서를 검색합니다.
Step 3− '쿼리 실행'버튼을 클릭하여이 쿼리를 실행합니다. 그러면 결과 블레이드에서 전체 문서가 검색되는 것을 볼 수 있습니다.
.Net SDK를 사용하여 문서 쿼리
다음은 .Net SDK를 사용하여 일부 문서 쿼리를 실행하는 단계입니다.
이 예에서는 방금 추가 한 새로 생성 된 문서를 쿼리하려고합니다.
Step 1 − CreateDocumentQuery를 호출하여 SelfLink 및 쿼리 텍스트를 기준으로 쿼리를 실행할 컬렉션을 전달합니다.
private async static Task QueryDocumentsWithPaging(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Query Documents (paged results) ****");
Console.WriteLine();
Console.WriteLine("Quering for all documents");
var sql = "SELECT * FROM c";
var query = client.CreateDocumentQuery(collection.SelfLink, sql).AsDocumentQuery();
while (query.HasMoreResults) {
var documents = await query.ExecuteNextAsync();
foreach (var document in documents) {
Console.WriteLine(" Id: {0}; Name: {1};", document.id, document.name);
}
}
Console.WriteLine();
}
이 쿼리는 또한 전체 컬렉션의 모든 문서를 반환하지만 이전과 같이 CreateDocumentQuery에서 .ToList를 호출하지 않고 모든 결과를 한 줄의 코드로 가져 오는 데 필요한만큼 많은 요청을 발행합니다.
Step 2 − 대신 AsDocumentQuery를 호출하면이 메서드는 HasMoreResults 속성이있는 쿼리 개체를 반환합니다.
Step 3 − HasMoreResults가 true이면 ExecuteNextAsync를 호출하여 다음 청크를 가져온 다음 해당 청크의 모든 내용을 덤프합니다.
Step 4− 원하는 경우 SQL 대신 LINQ를 사용하여 쿼리 할 수도 있습니다. 여기에 q에서 LINQ 쿼리를 정의했지만 .ToList를 실행할 때까지 실행되지 않습니다.
private static void QueryDocumentsWithLinq(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Query Documents (LINQ) ****");
Console.WriteLine();
Console.WriteLine("Quering for US customers (LINQ)");
var q =
from d in client.CreateDocumentQuery<Customer>(collection.DocumentsLink)
where d.Address.CountryRegionName == " United States"
select new {
Id = d.Id,
Name = d.Name,
City = d.Address.Location.City
};
var documents = q.ToList();
Console.WriteLine("Found {0} UK customers", documents.Count);
foreach (var document in documents) {
var d = document as dynamic;
Console.WriteLine(" Id: {0}; Name: {1}; City: {2}", d.Id, d.Name, d.City);
}
Console.WriteLine();
}
SDK는 LINQ 쿼리를 DocumentDB 용 SQL 구문으로 변환하여 LINQ 구문을 기반으로 SELECT 및 WHERE 절을 생성합니다.
Step 5 − 이제 CreateDocumentClient 작업에서 위의 쿼리를 호출합니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
//await CreateDocuments(client);
await QueryDocumentsWithPaging(client);
QueryDocumentsWithLinq(client);
}
}
위의 코드가 실행되면 다음과 같은 출력을 받게됩니다.
**** Query Documents (paged results) ****
Quering for all documents
Id: 7e9ad4fa-c432-4d1a-b120-58fd7113609f; Name: New Customer 1;
Id: 34e9873a-94c8-4720-9146-d63fb7840fad; Name: New Customer 1;
**** Query Documents (LINQ) ****
Quering for US customers (LINQ)
Found 2 UK customers
Id: 7e9ad4fa-c432-4d1a-b120-58fd7113609f; Name: New Customer 1; City: Brooklyn
Id: 34e9873a-94c8-4720-9146-d63fb7840fad; Name: New Customer 1; City: Brooklyn
이 장에서는 문서를 업데이트하는 방법을 배웁니다. Azure Portal을 사용하면 문서 탐색기에서 문서를 열고 텍스트 파일처럼 편집기에서 업데이트하여 문서를 쉽게 업데이트 할 수 있습니다.
'저장'버튼을 클릭합니다. 이제 .Net SDK를 사용하여 문서를 변경해야 할 때 바로 교체 할 수 있습니다. 지루할뿐만 아니라 문서를 수정하는 동안에는 원하지 않는 리소스 ID도 변경하므로 삭제하고 다시 만들 필요가 없습니다. 다음은 .Net SDK를 사용하여 문서를 업데이트하는 단계입니다.
isNew 속성이 true 인 문서를 쿼리 할 다음 ReplaceDocuments 작업을 살펴 보겠습니다.하지만 아무것도 없기 때문에 아무것도 얻지 못합니다. 따라서 이름이 New Customer로 시작하는 이전에 추가 한 문서를 수정 해 보겠습니다.
Step 1 −이 문서에 isNew 속성을 추가하고 그 값을 true로 설정합니다.
private async static Task ReplaceDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine(">>> Replace Documents <<<");
Console.WriteLine();
Console.WriteLine("Quering for documents with 'isNew' flag");
var sql = "SELECT * FROM c WHERE c.isNew = true";
var documents = client.CreateDocumentQuery(collection.SelfLink, sql).ToList();
Console.WriteLine("Documents with 'isNew' flag: {0} ", documents.Count);
Console.WriteLine();
Console.WriteLine("Quering for documents to be updated");
sql = "SELECT * FROM c WHERE STARTSWITH(c.name, 'New Customer') = true";
documents = client.CreateDocumentQuery(collection.SelfLink, sql).ToList();
Console.WriteLine("Found {0} documents to be updated", documents.Count);
foreach (var document in documents) {
document.isNew = true;
var result = await client.ReplaceDocumentAsync(document._self, document);
var updatedDocument = result.Resource;
Console.WriteLine("Updated document 'isNew' flag: {0}", updatedDocument.isNew);
}
Console.WriteLine();
Console.WriteLine("Quering for documents with 'isNew' flag");
sql = "SELECT * FROM c WHERE c.isNew = true";
documents = client.CreateDocumentQuery(collection.SelfLink, sql).ToList();
Console.WriteLine("Documents with 'isNew' flag: {0}: ", documents.Count);
Console.WriteLine();
}
Step 2 − 동일한 STARTSWITH 쿼리를 사용하여 업데이트 할 문서를 가져 오면 문서가 제공됩니다. 여기에서 동적 개체로 다시 가져옵니다.
Step 3 − isNew 속성을 첨부하고 각 문서에 대해 true로 설정합니다.
Step 4 − ReplaceDocumentAsync를 호출하여 업데이트 된 문서와 함께 문서의 SelfLink를 전달합니다.
이제 이것이 효과가 있음을 증명하기 위해 isNew가 true 인 문서를 쿼리합니다. CreateDocumentClient 작업에서 위의 쿼리를 호출 해 보겠습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
//await CreateDocuments(client);
//QueryDocumentsWithSql(client);
//await QueryDocumentsWithPaging(client);
//QueryDocumentsWithLinq(client);
await ReplaceDocuments(client);
}
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Replace Documents ****
Quering for documents with 'isNew' flag
Documents with 'isNew' flag: 0
Quering for documents to be updated
Found 2 documents to be updated
Updated document ‘isNew’ flag: True
Updated document ‘isNew’ flag: True
Quering for documents with 'isNew' flag
Documents with 'isNew' flag: 2
이 장에서는 DocumentDB 계정에서 문서를 삭제하는 방법에 대해 알아 봅니다. Azure Portal을 사용하면 문서 탐색기에서 문서를 열고 '삭제'옵션을 클릭하여 문서를 쉽게 삭제할 수 있습니다.
확인 메시지가 표시됩니다. 이제 예 버튼을 누르면 DocumentDB 계정에서 문서를 더 이상 사용할 수 없음을 알 수 있습니다.
이제 .Net SDK를 사용하여 문서를 삭제하려는 경우.
Step 1− 각 새 문서의 SelfLink를 가져 오기 위해 먼저 쿼리 할 이전에 본 것과 동일한 패턴입니다. 여기서는 필요하지 않은 문서 전체를 반환하는 SELECT *를 사용하지 않습니다.
Step 2 − 대신 목록에서 SelfLink를 선택한 다음 각 SelfLink에 대해 한 번에 하나씩 DeleteDocumentAsync를 호출하여 컬렉션에서 문서를 삭제합니다.
private async static Task DeleteDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine(">>> Delete Documents <<<");
Console.WriteLine();
Console.WriteLine("Quering for documents to be deleted");
var sql =
"SELECT VALUE c._self FROM c WHERE STARTSWITH(c.name, 'New Customer') = true";
var documentLinks =
client.CreateDocumentQuery<string>(collection.SelfLink, sql).ToList();
Console.WriteLine("Found {0} documents to be deleted", documentLinks.Count);
foreach (var documentLink in documentLinks) {
await client.DeleteDocumentAsync(documentLink);
}
Console.WriteLine("Deleted {0} new customer documents", documentLinks.Count);
Console.WriteLine();
}
Step 3 − 이제 CreateDocumentClient 작업에서 위의 DeleteDocuments를 호출 해 보겠습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
await DeleteDocuments(client);
}
}
위의 코드가 실행되면 다음과 같은 출력을 받게됩니다.
***** Delete Documents *****
Quering for documents to be deleted
Found 2 documents to be deleted
Deleted 2 new customer documents
DocumentDB와 같은 스키마없는 데이터베이스를 사용하면 데이터 모델에 대한 변경 사항을 매우 쉽게 수용 할 수 있지만 데이터에 대해 생각하는 데 시간을 투자해야합니다.
많은 옵션이 있습니다. 당연히 JSON 개체 그래프 또는 JSON 텍스트의 원시 문자열로 작업 할 수 있지만 컴파일 타임에 클래스를 정의하지 않고도 런타임에 속성에 바인딩 할 수있는 동적 개체를 사용할 수도 있습니다.
실제 C # 개체 또는 호출 된 엔터티 (비즈니스 도메인 클래스 일 수 있음)로 작업 할 수도 있습니다.
관계
문서의 계층 구조를 살펴 보겠습니다. 필수 id, lastName 및 isRegistered와 같은 몇 가지 최상위 속성이 있지만 중첩 속성도 있습니다.
{
"id": "AndersenFamily",
"lastName": "Andersen",
"parents": [
{ "firstName": "Thomas", "relationship": "father" },
{ "firstName": "Mary Kay", "relationship": "mother" }
],
"children": [
{
"firstName": "Henriette Thaulow",
"gender": "female",
"grade": 5,
"pets": [ { "givenName": "Fluffy", "type": "Rabbit" } ]
}
],
"location": { "state": "WA", "county": "King", "city": "Seattle"},
"isRegistered": true
}
예를 들어 parent 속성은 대괄호로 표시된 JSON 배열로 제공됩니다.
이 예제에서는 배열에 자식이 하나만 있더라도 자식을위한 또 다른 배열도 있습니다. 따라서 이것은 문서 내에서 일대 다 관계에 해당하는 모델을 만드는 방법입니다.
배열의 각 요소가 단순한 값이거나 다른 복잡한 객체, 심지어 다른 배열 일 수있는 배열을 사용하기 만하면됩니다.
따라서 한 패밀리에는 여러 부모와 여러 자식이있을 수 있으며 자식 개체를 보면 자식과 애완 동물 간의 일대 다 관계를위한 중첩 배열 인 애완 동물의 속성이 있습니다.
위치 속성의 경우 주, 카운티 및 도시의 세 가지 관련 속성을 하나의 개체로 결합합니다.
개체 배열을 포함하는 대신 이러한 방식으로 개체를 포함하는 것은 관계형 데이터베이스의 별도 테이블에있는 두 행간에 일대일 관계를 갖는 것과 유사합니다.
데이터 삽입
DocumentDB와 같은 문서 저장소에서 데이터 모델링을 시작할 때 엔티티를 JSON으로 표시되는 자체 포함 문서로 취급하십시오. 관계형 데이터베이스로 작업 할 때 우리는 항상 데이터를 정규화합니다.
데이터 정규화에는 일반적으로 고객과 같은 엔티티를 가져와 연락처 세부 정보 및 주소와 같은 신중한 데이터 조각으로 나누는 작업이 포함됩니다.
모든 연락처 세부 정보 및 주소와 함께 고객을 읽으려면 JOINS를 사용하여 런타임에 데이터를 효과적으로 집계해야합니다.
이제 문서 데이터베이스에서 자체 포함 된 엔터티와 동일한 데이터를 모델링하는 방법을 살펴 보겠습니다.
{
"id": "1",
"firstName": "Mark",
"lastName": "Upston",
"addresses": [
{
"line1": "232 Main Street",
"line2": "Unit 1",
"city": "Brooklyn",
"state": "NY",
"zip": 11229
}
],
"contactDetails": [
{"email": "[email protected]"},
{"phone": "+1 356 545-86455", "extension": 5555}
]
}
보시다시피 고객의 모든 정보가 단일 JSON 문서에 포함 된 고객 레코드를 비정규 화했습니다.
NoSQL에는 무료 스키마가 있으므로 연락처 세부 정보와 주소를 다른 형식으로 추가 할 수도 있습니다. NoSQL에서는 단일 읽기 작업으로 데이터베이스에서 고객 레코드를 검색 할 수 있습니다. 마찬가지로 레코드 업데이트도 단일 쓰기 작업입니다.
다음은 .Net SDK를 사용하여 문서를 만드는 단계입니다.
Step 1− DocumentClient를 인스턴스화합니다. 그런 다음 myfirstdb 데이터베이스를 쿼리하고 MyCollection 컬렉션도 쿼리합니다. MyCollection 컬렉션은이 개인 변수 컬렉션에 저장하므로 클래스 전체에서 액세스 할 수 있습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
await CreateDocuments(client);
}
}
Step 2 − CreateDocuments 작업에서 일부 문서를 생성합니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
},
postalCode = "11229", countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
}
첫 번째 문서는이 동적 개체에서 생성됩니다. 이것은 JSON처럼 보일 수 있지만 물론 그렇지 않습니다. 이것은 C # 코드이며 실제 .NET 개체를 생성하고 있지만 클래스 정의는 없습니다. 대신 속성은 개체가 초기화되는 방식에서 유추됩니다. 또한이 문서에 대해 Id 속성을 제공하지 않았 음을 알 수 있습니다.
Step 3 − 이제 CreateDocument를 살펴보면 데이터베이스와 컬렉션을 생성 할 때 본 것과 동일한 패턴으로 보입니다.
private async static Task<Document> CreateDocument(DocumentClient client,
object documentObject) {
var result = await client.CreateDocumentAsync(collection.SelfLink, documentObject);
var document = result.Resource;
Console.WriteLine("Created new document: {0}\r\n{1}", document.Id, document);
return result;
}
Step 4− 이번에는 문서를 추가 할 컬렉션의 SelfLink를 지정하는 CreateDocumentAsync를 호출합니다. 이 경우 시스템 생성 속성이있는 새 문서를 나타내는 리소스 속성이있는 응답을 반환합니다.
다음 CreateDocuments 작업에서 세 개의 문서를 만들었습니다.
첫 번째 문서에서 Document 개체는 리소스에서 상속되는 SDK의 정의 된 클래스이므로 모든 공통 리소스 속성이 있지만 스키마가없는 문서 자체를 정의하는 동적 속성도 포함됩니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
},
postalCode = "11229",
countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
var document2Definition = @" {
""name"": ""New Customer 2"",
""address"": {
""addressType"": ""Main Office"",
""addressLine1"": ""123 Main Street"",
""location"": {
""city"": ""Brooklyn"", ""stateProvinceName"": ""New York""
},
""postalCode"": ""11229"",
""countryRegionName"": ""United States""
}
}";
Document document2 = await CreateDocument(client, document2Definition);
Console.WriteLine("Created document {0} from JSON string", document2.Id);
Console.WriteLine();
var document3Definition = new Customer {
Name = "New Customer 3",
Address = new Address {
AddressType = "Main Office",
AddressLine1 = "123 Main Street",
Location = new Location {
City = "Brooklyn", StateProvinceName = "New York"
},
PostalCode = "11229",
CountryRegionName = "United States"
},
};
Document document3 = await CreateDocument(client, document3Definition);
Console.WriteLine("Created document {0} from typed object", document3.Id);
Console.WriteLine();
}
이 두 번째 문서는 원시 JSON 문자열로만 작동합니다. 이제 JavaScriptSerializer를 사용하여 문자열을 개체로 역 직렬화하는 CreateDocument에 대한 오버로드로 들어가서 첫 번째 문서를 만드는 데 사용한 것과 동일한 CreateDocument 메서드로 전달합니다.
세 번째 문서에서는 애플리케이션에 정의 된 C # 개체 Customer를 사용했습니다.
이 고객을 살펴 보겠습니다. 여기에는 주소가 위치를 포함하는 자체 속성이있는 중첩 된 개체 인 Id 및 주소 속성이 있으며 이는 또 다른 중첩 개체입니다.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DocumentDBDemo {
public class Customer {
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
// Must be nullable, unless generating unique values for new customers on client
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "address")]
public Address Address { get; set; }
}
public class Address {
[JsonProperty(PropertyName = "addressType")]
public string AddressType { get; set; }
[JsonProperty(PropertyName = "addressLine1")]
public string AddressLine1 { get; set; }
[JsonProperty(PropertyName = "location")]
public Location Location { get; set; }
[JsonProperty(PropertyName = "postalCode")]
public string PostalCode { get; set; }
[JsonProperty(PropertyName = "countryRegionName")]
public string CountryRegionName { get; set; }
}
public class Location {
[JsonProperty(PropertyName = "city")]
public string City { get; set; }
[JsonProperty(PropertyName = "stateProvinceName")]
public string StateProvinceName { get; set; }
}
}
울타리의 양쪽에서 적절한 규칙을 유지하기 위해 JSON 속성 속성도 있습니다.
따라서 중첩 된 자식 개체와 함께 New Customer 개체를 만들고 CreateDocument를 한 번 더 호출합니다. 고객 개체에 Id 속성이 있지만 값을 제공하지 않았으므로 DocumentDB는 이전 두 문서에서와 마찬가지로 GUID를 기반으로 하나를 생성했습니다.
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Create Documents ****
Created new document: 575882f0-236c-4c3d-81b9-d27780206b2c
{
"name": "New Customer 1",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"id": "575882f0-236c-4c3d-81b9-d27780206b2c",
"_rid": "kV5oANVXnwDGPgAAAAAAAA==",
"_ts": 1450037545,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDGPgAAAAAAAA==/",
"_etag": "\"00006fce-0000-0000-0000-566dd1290000\"",
"_attachments": "attachments/"
}
Created document 575882f0-236c-4c3d-81b9-d27780206b2c from dynamic object
Created new document: 8d7ad239-2148-4fab-901b-17a85d331056
{
"name": "New Customer 2",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"id": "8d7ad239-2148-4fab-901b-17a85d331056",
"_rid": "kV5oANVXnwDHPgAAAAAAAA==",
"_ts": 1450037545,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDHPgAAAAAAAA==/",
"_etag": "\"000070ce-0000-0000-0000-566dd1290000\"",
"_attachments": "attachments/"
}
Created document 8d7ad239-2148-4fab-901b-17a85d331056 from JSON string
Created new document: 49f399a8-80c9-4844-ac28-cd1dee689968
{
"id": "49f399a8-80c9-4844-ac28-cd1dee689968",
"name": "New Customer 3",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"_rid": "kV5oANVXnwDIPgAAAAAAAA==",
"_ts": 1450037546,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDIPgAAAAAAAA==/",
"_etag": "\"000071ce-0000-0000-0000-566dd12a0000\"",
"_attachments": "attachments/"
}
Created document 49f399a8-80c9-4844-ac28-cd1dee689968 from typed object
JSON 또는 JavaScript Object Notation은 사람이 읽을 수있는 데이터 교환을 위해 설계된 경량 텍스트 기반 개방형 표준이며 기계가 쉽게 구문 분석하고 생성 할 수 있습니다. JSON은 DocumentDB의 핵심입니다. 유선을 통해 JSON을 전송하고 JSON을 JSON으로 저장하며 JSON 트리를 인덱싱하여 전체 JSON 문서에 대한 쿼리를 허용합니다.
JSON 형식은 다음 데이터 유형을 지원합니다.
S. 아니. | 유형 및 설명 |
---|---|
1 | Number JavaScript의 배정 밀도 부동 소수점 형식 |
2 | String 백 슬래시 이스케이프가있는 큰 따옴표 유니 코드 |
삼 | Boolean 참 또는 거짓 |
4 | Array 순서가 지정된 일련의 값 |
5 | Value 문자열, 숫자, 참 또는 거짓, 널 등이 될 수 있습니다. |
6 | Object 키 : 값 쌍의 정렬되지 않은 컬렉션 |
7 | Whitespace 모든 토큰 쌍간에 사용할 수 있습니다. |
8 | Null 빈 |
간단한 예제 DateTime 유형을 살펴 보겠습니다. 고객 클래스에 생년월일을 추가합니다.
public class Customer {
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
// Must be nullable, unless generating unique values for new customers on client
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "address")]
public Address Address { get; set; }
[JsonProperty(PropertyName = "birthDate")]
public DateTime BirthDate { get; set; }
}
다음 코드와 같이 DateTime을 사용하여 저장, 검색 및 쿼리 할 수 있습니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
var document3Definition = new Customer {
Id = "1001",
Name = "Luke Andrew",
Address = new Address {
AddressType = "Main Office",
AddressLine1 = "123 Main Street",
Location = new Location {
City = "Brooklyn",
StateProvinceName = "New York"
},
PostalCode = "11229",
CountryRegionName = "United States"
},
BirthDate = DateTime.Parse(DateTime.Today.ToString()),
};
Document document3 = await CreateDocument(client, document3Definition);
Console.WriteLine("Created document {0} from typed object", document3.Id);
Console.WriteLine();
}
위의 코드를 컴파일하여 실행하고 문서가 생성되면 이제 생년월일이 추가 된 것을 볼 수 있습니다.
**** Create Documents ****
Created new document: 1001
{
"id": "1001",
"name": "Luke Andrew",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"birthDate": "2015-12-14T00:00:00",
"_rid": "Ic8LAMEUVgAKAAAAAAAAAA==",
"_ts": 1450113676,
"_self": "dbs/Ic8LAA==/colls/Ic8LAMEUVgA=/docs/Ic8LAMEUVgAKAAAAAAAAAA==/",
"_etag": "\"00002d00-0000-0000-0000-566efa8c0000\"",
"_attachments": "attachments/"
}
Created document 1001 from typed object
Microsoft는 최근에 SQL 문법에 대한 TOP 키워드와 같이 Azure DocumentDB를 쿼리 할 수있는 방법에 대한 여러 가지 개선 사항을 추가하여 쿼리를 더 빠르게 실행하고 리소스를 더 적게 사용하며 쿼리 연산자에 대한 제한을 늘리고 LINQ 연산자에 대한 추가 지원을 추가했습니다. .NET SDK.
처음 두 레코드 만 검색하는 간단한 예를 살펴 보겠습니다. 많은 레코드가 있고 그 중 일부만 검색하려는 경우 Top 키워드를 사용할 수 있습니다. 이 예에서 우리는 지진에 대한 많은 기록을 가지고 있습니다.
이제 처음 두 레코드 만 표시하려고합니다.
Step 1 − 쿼리 탐색기로 이동하여이 쿼리를 실행합니다.
SELECT * FROM c
WHERE c.magnitude > 2.5
아직 TOP 키워드를 지정하지 않았기 때문에 4 개의 레코드를 검색 한 것을 볼 수 있습니다.
Step 2− 이제 동일한 쿼리에 TOP 키워드를 사용합니다. 여기에서 TOP 키워드를 지정했으며 '2'는 두 개의 레코드 만 필요함을 의미합니다.
SELECT TOP 2 * FROM c
WHERE c.magnitude > 2.5
Step 3 − 이제이 쿼리를 실행하면 두 개의 레코드 만 검색되는 것을 볼 수 있습니다.
마찬가지로 .Net SDK를 사용하여 코드에서 TOP 키워드를 사용할 수 있습니다. 다음은 구현입니다.
private async static Task QueryDocumentsWithPaging(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Query Documents (paged results) ****");
Console.WriteLine();
Console.WriteLine("Quering for all documents");
var sql = "SELECT TOP 3 * FROM c";
var query = client
.CreateDocumentQuery(collection.SelfLink, sql)
.AsDocumentQuery();
while (query.HasMoreResults) {
var documents = await query.ExecuteNextAsync();
foreach (var document in documents) {
Console.WriteLine(" PublicId: {0}; Magnitude: {1};", document.publicid,
document.magnitude);
}
}
Console.WriteLine();
}
다음은 DocumentClient 및 지진 데이터베이스를 인스턴스화하는 CreateDocumentClient 작업입니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'earthquake'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'earthquakedata'").AsEnumerable().First();
await QueryDocumentsWithPaging(client);
}
}
위의 코드가 컴파일되고 실행되면 세 개의 레코드 만 검색되는 것을 볼 수 있습니다.
**** Query Documents (paged results) ****
Quering for all documents
PublicId: 2015p947400; Magnitude: 2.515176918;
PublicId: 2015p947373; Magnitude: 1.506774108;
PublicId: 2015p947329; Magnitude: 1.593394461;
Microsoft Azure DocumentDB는 JSON 문서에서 SQL을 사용하여 문서 쿼리를 지원합니다. 쿼리에서 ORDER BY 절을 사용하여 숫자 및 문자열에 대한 컬렉션의 문서를 정렬 할 수 있습니다. 절에는 결과를 검색해야하는 순서를 지정하는 선택적 ASC / DESC 인수가 포함될 수 있습니다.
JSON 문서가있는 다음 예제를 살펴 보겠습니다.
{
"id": "Food Menu",
"description": "Grapes, red or green (European type, such as Thompson seedless), raw",
"tags": [
{
"name": "grapes"
},
{
"name": "red or green (european type"
},
{
"name": "such as thompson seedless)"
},
{
"name": "raw"
}
],
"foodGroup": "Fruits and Fruit Juices",
"servings": [
{
"amount": 1,
"description": "cup",
"weightInGrams": 151
},
{
"amount": 10,
"description": "grapes",
"weightInGrams": 49
},
{
"amount": 1,
"description": "NLEA serving",
"weightInGrams": 126
}
]
}
다음은 결과를 내림차순으로 정렬하는 SQL 쿼리입니다.
SELECT f.description, f.foodGroup,
f.servings[2].description AS servingDescription,
f.servings[2].weightInGrams AS servingWeight
FROM f
ORDER BY f.servings[2].weightInGrams DESC
위 쿼리가 실행되면 다음과 같은 출력이 표시됩니다.
[
{
"description": "Grapes, red or green (European type, such as Thompson
seedless), raw",
"foodGroup": "Fruits and Fruit Juices",
"servingDescription": "NLEA serving",
"servingWeight": 126
}
]
기본적으로 DocumentDB는 문서가 데이터베이스에 추가되는 즉시 문서의 모든 속성을 자동으로 인덱싱합니다. 그러나 인덱싱 할 필요가없는 특정 문서 및 / 또는 속성이있는 경우 스토리지 및 처리 오버 헤드를 줄이는 자체 인덱싱 정책을 제어하고 미세 조정할 수 있습니다.
모든 속성을 자동으로 인덱싱하도록 DocumentDB에 지시하는 기본 인덱싱 정책은 많은 일반적인 시나리오에 적합합니다. 그러나 인덱싱되는 항목과 인덱싱되지 않는 항목 및 인덱싱과 관련된 기타 기능을 정확하게 제어하는 사용자 지정 정책을 구현할 수도 있습니다.
DocumentDB는 다음 유형의 인덱싱을 지원합니다.
- Hash
- Range
해시시
해시 인덱스를 사용하면 같음에 대한 효율적인 쿼리를 수행 할 수 있습니다. 즉,보다 작거나 크거나 사이와 같은 값 범위에서 일치하는 것이 아니라 지정된 속성이 정확한 값과 같은 문서를 검색 할 수 있습니다.
해시 인덱스를 사용하여 범위 쿼리를 수행 할 수 있지만 DocumentDB는 해시 인덱스를 사용하여 일치하는 문서를 찾을 수 없으며 대신 각 문서를 순차적으로 스캔하여 범위 쿼리에서 선택해야하는지 여부를 결정해야합니다.
해시 인덱스 만있는 속성에서는 ORDER BY 절을 사용하여 문서를 정렬 할 수 없습니다.
범위
속성에 대해 정의 된 범위 인덱스 인 DocumentDB를 사용하면 값 범위에 대해 문서를 효율적으로 쿼리 할 수 있습니다. 또한 ORDER BY를 사용하여 해당 속성에 대한 쿼리 결과를 정렬 할 수 있습니다.
DocumentDB를 사용하면 일부 또는 모든 속성에서 해시 및 범위 인덱스를 모두 정의 할 수 있으므로 ORDER BY뿐만 아니라 효율적인 같음 및 범위 쿼리를 사용할 수 있습니다.
인덱싱 정책
모든 컬렉션에는 모든 문서의 모든 속성에서 숫자와 문자열에 사용되는 인덱스 유형을 지정하는 인덱싱 정책이 있습니다.
문서가 컬렉션에 추가 될 때 문서가 자동으로 인덱싱되는지 여부를 제어 할 수도 있습니다.
자동 인덱싱은 기본적으로 활성화되어 있지만 문서를 추가 할 때 해당 동작을 재정 의하여 특정 문서를 인덱싱하지 않도록 DocumentDB에 지시 할 수 있습니다.
자동 인덱싱을 비활성화하여 기본적으로 문서가 컬렉션에 추가 될 때 인덱싱되지 않도록 할 수 있습니다. 마찬가지로 문서 수준에서이를 재정의하고 문서를 컬렉션에 추가 할 때 특정 문서를 인덱싱하도록 DocumentDB에 지시 할 수 있습니다. 이를 수동 인덱싱이라고합니다.
인덱싱 포함 / 제외
인덱싱 정책은 인덱스에 포함되거나 제외되어야하는 경로를 정의 할 수도 있습니다. 이 기능은 쿼리하지 않는 문서의 특정 부분과 수행하는 특정 부분이 있다는 것을 알고있는 경우 유용합니다.
이러한 경우 컬렉션에 추가 된 각 문서의 특정 부분 만 인덱싱하도록 DocumentDB에 지시하여 인덱싱 오버 헤드를 줄일 수 있습니다.
자동 인덱싱
자동 인덱싱의 간단한 예를 살펴 보겠습니다.
Step 1 − 먼저 오토 인덱싱이라는 컬렉션을 만들고 명시 적으로 정책을 제공하지 않고이 컬렉션은 기본 인덱싱 정책을 사용합니다. 즉,이 컬렉션에서 자동 인덱싱이 활성화됩니다.
여기서는 데이터베이스 자체 링크에 ID 기반 라우팅을 사용하므로 컬렉션을 만들기 전에 리소스 ID를 알거나 쿼리 할 필요가 없습니다. mydb라는 데이터베이스 ID 만 사용할 수 있습니다.
Step 2 − 이제 Upston이라는 성이있는 두 개의 문서를 만들어 보겠습니다.
private async static Task AutomaticIndexing(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Override Automatic Indexing ****");
// Create collection with automatic indexing
var collectionDefinition = new DocumentCollection {
Id = "autoindexing"
};
var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
collectionDefinition);
// Add a document (indexed)
dynamic indexedDocumentDefinition = new {
id = "MARK",
firstName = "Mark",
lastName = "Upston",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document indexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/autoindexing", indexedDocumentDefinition);
// Add another document (request no indexing)
dynamic unindexedDocumentDefinition = new {
id = "JANE",
firstName = "Jane",
lastName = "Upston",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document unindexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/autoindexing", unindexedDocumentDefinition,
new RequestOptions { IndexingDirective = IndexingDirective.Exclude });
//Unindexed document won't get returned when querying on non-ID (or selflink) property
var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing", "SELECT *
FROM c WHERE c.lastName = 'Doe'").ToList();
Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);
// Unindexed document will get returned when using no WHERE clause
var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
"SELECT * FROM c").ToList();
Console.WriteLine("All documents: {0}", allDocs.Count);
// Unindexed document will get returned when querying by ID (or self-link) property
Document janeDoc = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
"SELECT * FROM c WHERE c.id = 'JANE'").AsEnumerable().FirstOrDefault();
Console.WriteLine("Unindexed document self-link: {0}", janeDoc.SelfLink);
// Delete the collection
await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/autoindexing");
}
Mark Upston의 첫 번째 항목은 컬렉션에 추가 된 다음 기본 인덱싱 정책에 따라 즉시 자동으로 인덱싱됩니다.
그러나 Mark Upston에 대한 두 번째 문서가 추가되면 컬렉션의 인덱싱 정책에도 불구하고이 문서를 인덱싱하지 않도록 DocumentDB에 명시 적으로 지시하는 IndexingDirective.Exclude로 요청 옵션을 전달했습니다.
마지막에 두 문서에 대해 서로 다른 유형의 쿼리가 있습니다.
Step 3 − CreateDocumentClient에서 AutomaticIndexing 작업을 호출 해 보겠습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await AutomaticIndexing(client);
}
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Override Automatic Indexing ****
Documents WHERE lastName = 'Upston': 1
All documents: 2
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oAOEkfQA=/docs/kV5oAOEkfQACA
AAAAAAAAA==/
보시다시피 이러한 문서가 두 개 있지만 Mark에 대한 문서는 인덱싱되지 않았으므로 쿼리는 Mark에 대한 문서 만 반환합니다. 컬렉션의 모든 문서를 검색하기 위해 WHERE 절없이 다시 쿼리하면 두 문서가 모두 포함 된 결과 집합을 얻습니다. 이는 인덱싱되지 않은 문서가 항상 WHERE 절이없는 쿼리에 의해 반환되기 때문입니다.
ID 또는 자체 링크로 색인화되지 않은 문서를 검색 할 수도 있습니다. 따라서 Mark의 ID 인 MARK로 문서를 쿼리하면 DocumentDB가 컬렉션에서 색인화되지 않은 문서를 반환하는 것을 볼 수 있습니다.
수동 인덱싱
자동 인덱싱을 재정 의하여 수동 인덱싱의 간단한 예를 살펴 보겠습니다.
Step 1− 먼저 manualindexing이라는 컬렉션을 만들고 명시 적으로 자동 인덱싱을 비활성화하여 기본 정책을 재정의합니다. 즉, 달리 요청하지 않는 한이 컬렉션에 추가 된 새 문서는 인덱싱되지 않습니다.
private async static Task ManualIndexing(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Manual Indexing ****");
// Create collection with manual indexing
var collectionDefinition = new DocumentCollection {
Id = "manualindexing",
IndexingPolicy = new IndexingPolicy {
Automatic = false,
},
};
var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
collectionDefinition);
// Add a document (unindexed)
dynamic unindexedDocumentDefinition = new {
id = "MARK",
firstName = "Mark",
lastName = "Doe",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document unindexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/manualindexing", unindexedDocumentDefinition);
// Add another document (request indexing)
dynamic indexedDocumentDefinition = new {
id = "JANE",
firstName = "Jane",
lastName = "Doe",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document indexedDocument = await client.CreateDocumentAsync
("dbs/mydb/colls/manualindexing", indexedDocumentDefinition, new RequestOptions {
IndexingDirective = IndexingDirective.Include });
//Unindexed document won't get returned when querying on non-ID (or selflink) property
var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT * FROM c WHERE c.lastName = 'Doe'").ToList();
Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);
// Unindexed document will get returned when using no WHERE clause
var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT * FROM c").ToList();
Console.WriteLine("All documents: {0}", allDocs.Count);
// Unindexed document will get returned when querying by ID (or self-link) property
Document markDoc = client
.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT * FROM c WHERE c.id = 'MARK'")
.AsEnumerable().FirstOrDefault();
Console.WriteLine("Unindexed document self-link: {0}", markDoc.SelfLink);
await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/manualindexing");
}
Step 2− 이제 이전과 동일한 두 개의 문서를 다시 생성합니다. 이번에는 Mark의 문서에 대한 특별한 요청 옵션을 제공하지 않을 것입니다. 컬렉션의 인덱싱 정책으로 인해이 문서는 인덱싱되지 않습니다.
Step 3 − 이제 Mark에 대한 두 번째 문서를 추가 할 때 IndexingDirective.Include와 함께 RequestOptions를 사용하여 DocumentDB에이 문서를 인덱싱해야 함을 알리며, 이는 안된다고 말하는 컬렉션의 인덱싱 정책을 재정의합니다.
마지막에 두 문서에 대해 서로 다른 유형의 쿼리가 있습니다.
Step 4 − CreateDocumentClient에서 ManualIndexing 작업을 호출 해 보겠습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await ManualIndexing(client);
}
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Manual Indexing ****
Documents WHERE lastName = 'Upston': 1
All documents: 2
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oANHJPgE=/docs/kV5oANHJPgEBA
AAAAAAAAA==/
다시 말하지만 쿼리는 두 문서 중 하나만 반환하지만 이번에는 명시 적으로 인덱싱을 요청한 Jane Doe를 반환합니다. 그러나 이전과 마찬가지로 WHERE 절없이 쿼리하면 Mark에 대한 색인화되지 않은 문서를 포함하여 컬렉션의 모든 문서가 검색됩니다. 또한 색인이 생성되지 않은 문서에도 DocumentDB가 반환하는 ID로 색인이 생성되지 않은 문서를 쿼리 할 수 있습니다.
Microsoft 추가 geospatial support, 문서에 위치 데이터를 저장하고 점과 다각형 사이의 거리와 교차점에 대한 공간 계산을 수행 할 수 있습니다.
공간 데이터는 공간에서 물체의 위치와 모양을 설명합니다.
일반적으로 사람의 위치, 관심 장소 또는 도시 또는 호수의 경계를 나타내는 데 사용할 수 있습니다.
일반적인 사용 사례에는 종종 근접 쿼리가 포함됩니다. 예 : "현재 위치 근처의 모든 대학 찾기".
ㅏ Point정확한 위치 (예 : 특정 대학의 주소)를 나타내는 공간의 단일 위치를 나타냅니다. 점은 좌표 쌍 (경도 및 위도)을 사용하여 DocumentDB에 표시됩니다. 다음은 JSON 포인트의 예입니다.
{
"type":"Point",
"coordinates":[ 28.3, -10.7 ]
}
대학의 위치가 포함 된 간단한 예를 살펴 보겠습니다.
{
"id":"case-university",
"name":"CASE: Center For Advanced Studies In Engineering",
"city":"Islamabad",
"location": {
"type":"Point",
"coordinates":[ 33.7194136, -73.0964862 ]
}
}
위치를 기반으로 대학 이름을 검색하려면 다음 쿼리를 사용할 수 있습니다.
SELECT c.name FROM c
WHERE c.id = "case-university" AND ST_ISVALID({
"type":"Point",
"coordinates":[ 33.7194136, -73.0964862 ]})
위 쿼리가 실행되면 다음과 같은 출력이 표시됩니다.
[
{
"name": "CASE: Center For Advanced Studies In Engineering"
}
]
.NET에서 지리 공간 데이터로 문서 작성
지리 공간 데이터로 문서를 작성할 수 있습니다. 대학 문서가 작성되는 간단한 예를 살펴 보겠습니다.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
var uniDocument = new UniversityProfile {
Id = "nust",
Name = "National University of Sciences and Technology",
City = "Islamabad",
Loc = new Point(33.6455715, 72.9903447)
};
Document document = await CreateDocument(client, uniDocument);
Console.WriteLine("Created document {0} from typed object", document.Id);
Console.WriteLine();
}
다음은 UniversityProfile 클래스의 구현입니다.
public class UniversityProfile {
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("location")]
public Point Loc { get; set; }
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** Create Documents ****
Created new document: nust
{
"id": "nust",
"name": "National University of Sciences and Technology",
"city": "Islamabad",
"location": {
"type": "Point",
"coordinates": [
33.6455715,
72.9903447
]
},
"_rid": "Ic8LAMEUVgANAAAAAAAAAA==",
"_ts": 1450200910,
"_self": "dbs/Ic8LAA==/colls/Ic8LAMEUVgA=/docs/Ic8LAMEUVgANAAAAAAAAAA==/",
"_etag": "\"00004100-0000-0000-0000-56704f4e0000\"",
"_attachments": "attachments/"
}
Created document nust from typed object
데이터베이스가 10GB 이상으로 커지기 시작하면 새 컬렉션을 만든 다음 더 많은 컬렉션에 데이터를 분산하거나 분할하여 간단히 확장 할 수 있습니다.
조만간 10GB 용량의 단일 컬렉션은 데이터베이스를 포함하기에 충분하지 않을 것입니다. 이제 10GB는 그다지 큰 숫자처럼 들리지 않을 수 있지만, 우리는 일반 텍스트 인 JSON 문서를 저장하고 있으며 인덱스에 대한 스토리지 오버 헤드를 고려하더라도 10GB에 많은 일반 텍스트 문서를 저장할 수 있습니다.
확장 성과 관련하여 스토리지가 유일한 문제는 아닙니다. 컬렉션에서 사용할 수있는 최대 처리량은 S3 컬렉션에서 얻을 수있는 초당 250 개의 요청 단위입니다. 따라서 더 높은 처리량이 필요한 경우 여러 컬렉션으로 분할하여 확장해야합니다. 스케일 아웃 파티셔닝이라고도합니다.horizontal partitioning.
Azure DocumentDB를 사용하여 데이터를 분할하는 데 사용할 수있는 많은 접근 방식이 있습니다. 다음은 가장 일반적인 전략입니다-
- 스필 오버 파티셔닝
- 범위 분할
- 조회 분할
- 해시 파티셔닝
스필 오버 파티셔닝
스필 오버 파티셔닝은 파티션 키가 없기 때문에 가장 간단한 전략입니다. 많은 것에 대해 확신이 없을 때 시작하는 것이 좋은 선택입니다. 단일 컬렉션 이상으로 확장해야하는지 또는 추가해야 할 컬렉션 수 또는 추가해야하는 속도를 모를 수도 있습니다.
스필 오버 파티셔닝은 단일 컬렉션으로 시작되며 파티션 키가 없습니다.
컬렉션은 10GB 한도에 가까워 질 때까지 점점 커지기 시작하고 더 커집니다.
용량이 90 %에 도달하면 새 컬렉션으로 넘어 가서 새 문서에 사용하기 시작합니다.
데이터베이스가 더 많은 수의 컬렉션으로 확장되면 파티션 키를 기반으로하는 전략으로 전환 할 수 있습니다.
이 작업을 수행 할 때 마이그레이션하려는 전략에 따라 문서를 다른 컬렉션으로 이동하여 데이터 균형을 다시 조정해야합니다.
범위 분할
가장 일반적인 전략 중 하나는 범위 분할입니다. 이 접근 방식을 사용하면 문서의 파티션 키가 속할 수있는 값 범위를 결정하고 해당 범위에 해당하는 컬렉션으로 문서를 보냅니다.
날짜는 정의 된 날짜 범위에 속하는 문서를 보관하기 위해 컬렉션을 만드는이 전략에서 매우 일반적으로 사용됩니다. 충분히 작은 범위를 정의 할 때 컬렉션이 10GB 제한을 초과하지 않을 것이라고 확신 할 수 있습니다. 예를 들어, 단일 컬렉션이 한 달 동안 문서를 합리적으로 처리 할 수있는 시나리오가있을 수 있습니다.
또한 대부분의 사용자가 이번 달 또는 지난 달의 데이터 인 현재 데이터를 쿼리하지만 사용자는 훨씬 오래된 데이터를 거의 검색하지 않는 경우 일 수 있습니다. 따라서 6 월에 구매할 수있는 가장 비싼 컬렉션이며 얻을 수있는 최고의 처리량을 제공하는 S3 컬렉션으로 시작합니다.
7 월에 7 월 데이터를 저장하기 위해 다른 S3 컬렉션을 구입하고 6 월 데이터를 저렴한 S2 컬렉션으로 축소합니다. 그런 다음 8 월에 또 다른 S3 컬렉션을 얻고 7 월은 S2로, 6 월은 S1로 줄입니다. 매월 현재 데이터를 높은 처리량에 사용할 수 있도록 유지하고 오래된 데이터는 낮은 처리량으로 사용할 수 있도록 유지합니다.
쿼리가 파티션 키를 제공하는 한 쿼리해야하는 컬렉션 만 쿼리되며 스필 오버 파티셔닝에서 발생하는 것처럼 데이터베이스의 모든 컬렉션이 쿼리되지 않습니다.
조회 분할
조회 파티셔닝을 사용하면 파티션 키를 기반으로 문서를 특정 컬렉션으로 라우팅하는 파티션 맵을 정의 할 수 있습니다. 예를 들어 지역별로 분할 할 수 있습니다.
모든 미국 문서를 한 컬렉션에 저장하고, 모든 유럽 문서를 다른 컬렉션에 저장하고, 다른 지역의 모든 문서를 세 번째 컬렉션에 저장합니다.
이 파티션 맵과 조회 파티션 해결 프로그램을 사용하면 각 문서에 포함 된 영역 속성 인 파티션 키를 기반으로 문서를 만들 컬렉션과 쿼리 할 컬렉션을 파악할 수 있습니다.
해시 파티셔닝
해시 파티셔닝에서 파티션은 해시 함수의 값에 따라 할당되므로 여러 파티션에 요청과 데이터를 균등하게 분산 할 수 있습니다.
이것은 일반적으로 많은 개별 클라이언트에서 생성되거나 소비되는 데이터를 분할하는 데 사용되며 사용자 프로필, 카탈로그 항목 등을 저장하는 데 유용합니다.
.NET SDK에서 제공하는 RangePartitionResolver를 사용한 범위 분할의 간단한 예를 살펴 보겠습니다.
Step 1− 새 DocumentClient를 만들고 CreateCollections 작업에서 두 개의 컬렉션을 생성합니다. 하나는 A-M으로 시작하는 사용자 ID를 가진 사용자에 대한 문서를 포함하고 다른 하나는 사용자 ID N-Z에 대한 문서를 포함합니다.
private static async Task CreateCollections(DocumentClient client) {
await client.CreateDocumentCollectionAsync(“dbs/myfirstdb”, new DocumentCollection {
Id = “CollectionAM” });
await client.CreateDocumentCollectionAsync(“dbs/myfirstdb”, new DocumentCollection {
Id = “CollectionNZ” });
}
Step 2 − 데이터베이스에 대한 범위 분석기를 등록합니다.
Step 3− 파티션 키의 데이터 유형 인 새로운 RangePartitionResolver <string>을 생성합니다. 생성자는 두 개의 매개 변수, 파티션 키의 속성 이름과 리졸버에 대해 미리 정의하는 범위 및 해당 컬렉션의 목록 인 샤드 맵 또는 파티션 맵인 사전을 사용합니다.
private static void RegisterRangeResolver(DocumentClient client) {
//Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
var resolver = new RangePartitionResolver<string>(
"userId", new Dictionary<Range<string>, string>() {
{ new Range<string>("A", "M\uffff"), "dbs/myfirstdb/colls/CollectionAM" },
{ new Range<string>("N", "Z\uffff"), "dbs/myfirstdb/colls/CollectionNZ" },
});
client.PartitionResolvers["dbs/myfirstdb"] = resolver;
}
여기서 가능한 가장 큰 UTF-8 값을 인코딩해야합니다. 그렇지 않으면 첫 번째 범위는 하나의 단일 M을 제외한 어떤 M에서도 일치하지 않으며 두 번째 범위의 Z에서도 마찬가지입니다. 따라서 여기에서 인코딩 된 값을 파티션 키와 일치하는 와일드 카드로 생각할 수 있습니다.
Step 4− 리졸버를 생성 한 후 현재 DocumentClient로 데이터베이스에 등록합니다. 그렇게하려면 PartitionResolver의 사전 속성에 할당하기 만하면됩니다.
평소처럼 컬렉션이 아닌 데이터베이스에 대한 문서를 만들고 쿼리합니다. 해석기는이 맵을 사용하여 요청을 적절한 컬렉션으로 라우팅합니다.
이제 몇 가지 문서를 만들어 보겠습니다. 먼저 userId Kirk에 대해 하나를 생성 한 다음 Spock에 대해 하나를 생성합니다.
private static async Task CreateDocumentsAcrossPartitions(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents Across Partitions ****");
var kirkDocument = await client.CreateDocumentAsync("dbs/myfirstdb", new { userId =
"Kirk", title = "Captain" });
Console.WriteLine("Document 1: {0}", kirkDocument.Resource.SelfLink);
var spockDocument = await client.CreateDocumentAsync("dbs/myfirstdb", new { userId =
"Spock", title = "Science Officer" });
Console.WriteLine("Document 2: {0}", spockDocument.Resource.SelfLink);
}
여기서 첫 번째 매개 변수는 특정 컬렉션이 아닌 데이터베이스에 대한 자체 링크입니다. 파티션 리졸버 없이는 불가능하지만 하나만 있으면 원활하게 작동합니다.
두 문서 모두 myfirstdb 데이터베이스에 저장되었지만, RangePartitionResolver가 제대로 작동하는 경우 Kirk는 A부터 M까지의 컬렉션에 저장되고 Spock은 N부터 Z까지의 컬렉션에 저장된다는 것을 알고 있습니다.
다음 코드에 표시된대로 CreateDocumentClient 작업에서이를 호출 해 보겠습니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await CreateCollections(client);
RegisterRangeResolver(client);
await CreateDocumentsAcrossPartitions(client);
}
}
위의 코드가 실행되면 다음과 같은 출력을 받게됩니다.
**** Create Documents Across Partitions ****
Document 1: dbs/Ic8LAA==/colls/Ic8LAO2DxAA=/docs/Ic8LAO2DxAABAAAAAAAAAA==/
Document 2: dbs/Ic8LAA==/colls/Ic8LAP12QAE=/docs/Ic8LAP12QAEBAAAAAAAAAA==/
두 문서의 자체 링크는 두 개의 개별 컬렉션에 존재하기 때문에 리소스 ID가 다릅니다.
DocumentDB 데이터 마이그레이션 도구를 사용하면 데이터를 DocumentDB로 쉽게 마이그레이션 할 수 있습니다. DocumentDB 데이터 마이그레이션 도구는 Microsoft 다운로드 센터에서 다운로드 할 수있는 무료 오픈 소스 유틸리티입니다.https://www.microsoft.com/
마이그레이션 도구는 많은 데이터 소스를 지원하며, 그중 일부는 아래에 나열되어 있습니다.
- SQL 서버
- JSON 파일
- CSV (쉼표로 구분 된 값)의 플랫 파일
- MongoDB
- Azure 테이블 저장소
- Amazon DynamoDB
- HBase 및 기타 DocumentDB 데이터베이스
DocumentDB 데이터 마이그레이션 도구를 다운로드 한 후 zip 파일을 추출하십시오.
다음 스크린 샷과 같이이 폴더에서 두 개의 실행 파일을 볼 수 있습니다.
먼저 명령 줄 인터페이스가있는 콘솔 버전 인 dt.exe가 있고 그래픽 사용자 인터페이스가있는 데스크톱 버전 인 dtui.exe가 있습니다.
GUI 버전을 시작하겠습니다.
환영 페이지를 볼 수 있습니다. 소스 정보 페이지에서 '다음'을 클릭하십시오.
여기에서 데이터 소스를 구성 할 수 있으며 드롭 다운 메뉴에서 지원되는 많은 선택 항목을 볼 수 있습니다.
선택하면 나머지 소스 정보 페이지도 그에 따라 변경됩니다.
DocumentDB 데이터 마이그레이션 도구를 사용하여 데이터를 DocumentDB로 가져 오는 것은 매우 쉽습니다. 위의 예제를 실행하고 다른 데이터 파일도 사용하는 것이 좋습니다.
DocumentDB는 DocumentDB 리소스에 대한 액세스를 제어하는 개념을 제공합니다. DocumentDB 리소스에 대한 액세스는 마스터 키 토큰 또는 리소스 토큰에 의해 관리됩니다. 리소스 토큰을 기반으로하는 연결은 토큰으로 지정된 리소스에만 액세스 할 수 있으며 다른 리소스에는 액세스 할 수 없습니다. 리소스 토큰은 사용자 권한을 기반으로합니다.
먼저 한 명 이상의 사용자를 생성하고 이들은 데이터베이스 수준에서 정의됩니다.
그런 다음 각 사용자가 액세스 할 수 있도록 허용 할 리소스를 기반으로 각 사용자에 대해 하나 이상의 권한을 만듭니다.
각 권한은 주어진 리소스에 대한 읽기 전용 또는 전체 액세스를 허용하고 데이터베이스 내의 모든 사용자 리소스가 될 수있는 리소스 토큰을 생성합니다.
사용자는 데이터베이스 수준에서 정의되고 권한은 각 사용자에 대해 정의됩니다.
사용자 및 권한은 데이터베이스의 모든 컬렉션에 적용됩니다.
DocumentDB에서 세분화 된 보안을 달성하기 위해 사용자 및 권한을 정의하는 방법을 배우는 간단한 예제를 살펴 보겠습니다.
새 DocumentClient로 시작하여 myfirstdb 데이터베이스를 쿼리합니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
var alice = await CreateUser(client, "Alice");
var tom = await CreateUser(client, "Tom");
}
}
다음은 CreateUser에 대한 구현입니다.
private async static Task<User> CreateUser(DocumentClient client, string userId) {
Console.WriteLine();
Console.WriteLine("**** Create User {0} in {1} ****", userId, database.Id);
var userDefinition = new User { Id = userId };
var result = await client.CreateUserAsync(database.SelfLink, userDefinition);
var user = result.Resource;
Console.WriteLine("Created new user");
ViewUser(user);
return user;
}
Step 1− 생성 한 리소스와 마찬가지로 Alice와 Tom이라는 두 명의 사용자를 생성하고 원하는 Id로 정의 객체를 생성하고 create 메서드를 호출합니다.이 경우 데이터베이스의 SelfLink 및 userDefinition을 사용하여 CreateUserAsync를 호출합니다. 새로 생성 된 사용자 객체를 얻은 리소스 속성의 결과를 반환합니다.
이제 데이터베이스에서이 두 명의 새로운 사용자를 확인합니다.
private static void ViewUsers(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** View Users in {0} ****", database.Id);
var users = client.CreateUserQuery(database.UsersLink).ToList();
var i = 0;
foreach (var user in users) {
i++;
Console.WriteLine();
Console.WriteLine("User #{0}", i);
ViewUser(user);
}
Console.WriteLine();
Console.WriteLine("Total users in database {0}: {1}", database.Id, users.Count);
}
private static void ViewUser(User user) {
Console.WriteLine("User ID: {0} ", user.Id);
Console.WriteLine("Resource ID: {0} ", user.ResourceId);
Console.WriteLine("Self Link: {0} ", user.SelfLink);
Console.WriteLine("Permissions Link: {0} ", user.PermissionsLink);
Console.WriteLine("Timestamp: {0} ", user.Timestamp);
}
Step 2− 데이터베이스의 UsersLink에 대해 CreateUserQuery를 호출하여 모든 사용자 목록을 검색합니다. 그런 다음 반복하여 속성을 확인합니다.
이제 먼저 생성해야합니다. 따라서 Alice가 MyCollection 컬렉션에 대한 읽기 / 쓰기 권한을 허용하려고했지만 Tom은 컬렉션의 문서 만 읽을 수 있습니다.
await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All,
collection);
await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read,
collection);
Step 3− MyCollection 컬렉션 인 리소스에 대한 권한을 생성하여 해당 리소스에 SelfLink를 가져와야합니다.
Step 4 − 그런 다음 Permission.All on this collection for Alice와 Permission. Tom을위한이 컬렉션을 읽어보세요.
다음은 CreatePermission에 대한 구현입니다.
private async static Task CreatePermission(DocumentClient client, User user,
string permId, PermissionMode permissionMode, string resourceLink) {
Console.WriteLine();
Console.WriteLine("**** Create Permission {0} for {1} ****", permId, user.Id);
var permDefinition = new Permission {
Id = permId,
PermissionMode = permissionMode,
ResourceLink = resourceLink
};
var result = await client.CreatePermissionAsync(user.SelfLink, permDefinition);
var perm = result.Resource;
Console.WriteLine("Created new permission");
ViewPermission(perm);
}
지금 쯤 예상하게 되겠지만, 새로운 권한에 대한 정의 개체를 생성하여이를 수행합니다. 여기에는 Id와 Permission.All 또는 Permission.Read 중 하나 인 permissionMode와 보안되는 리소스의 SelfLink가 포함됩니다. 허가에 의해.
Step 5 − CreatePermissionAsync를 호출하고 결과의 리소스 속성에서 생성 된 권한을 가져옵니다.
생성 된 권한을보기위한 ViewPermissions 구현은 다음과 같습니다.
private static void ViewPermissions(DocumentClient client, User user) {
Console.WriteLine();
Console.WriteLine("**** View Permissions for {0} ****", user.Id);
var perms = client.CreatePermissionQuery(user.PermissionsLink).ToList();
var i = 0;
foreach (var perm in perms) {
i++;
Console.WriteLine();
Console.WriteLine("Permission #{0}", i);
ViewPermission(perm);
}
Console.WriteLine();
Console.WriteLine("Total permissions for {0}: {1}", user.Id, perms.Count);
}
private static void ViewPermission(Permission perm) {
Console.WriteLine("Permission ID: {0} ", perm.Id);
Console.WriteLine("Resource ID: {0} ", perm.ResourceId);
Console.WriteLine("Permission Mode: {0} ", perm.PermissionMode);
Console.WriteLine("Token: {0} ", perm.Token);
Console.WriteLine("Timestamp: {0} ", perm.Timestamp);
}
이번에는 사용자의 권한 링크에 대한 권한 쿼리이며 사용자에게 반환 된 각 권한을 간단히 나열합니다.
Alice와 Tom의 권한을 삭제하겠습니다.
await DeletePermission(client, alice, "Alice Collection Access");
await DeletePermission(client, tom, "Tom Collection Access");
다음은 DeletePermission에 대한 구현입니다.
private async static Task DeletePermission(DocumentClient client, User user,
string permId) {
Console.WriteLine();
Console.WriteLine("**** Delete Permission {0} from {1} ****", permId, user.Id);
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id",
Parameters = new SqlParameterCollection {
new SqlParameter { Name = "@id", Value = permId }
}
};
Permission perm = client.CreatePermissionQuery(user.PermissionsLink, query)
.AsEnumerable().First();
await client.DeletePermissionAsync(perm.SelfLink);
Console.WriteLine("Deleted permission {0} from user {1}", permId, user.Id);
}
Step 6 − 권한을 삭제하려면 권한 ID로 쿼리하여 SelfLink를 가져온 다음 SelfLink를 사용하여 권한을 삭제합니다.
다음으로 사용자를 삭제하겠습니다. 두 사용자를 모두 삭제하겠습니다.
await DeleteUser(client, "Alice");
await DeleteUser(client, "Tom");
다음은 DeleteUser의 구현입니다.
private async static Task DeleteUser(DocumentClient client, string userId) {
Console.WriteLine();
Console.WriteLine("**** Delete User {0} in {1} ****", userId, database.Id);
var query = new SqlQuerySpec {
QueryText = "SELECT * FROM c WHERE c.id = @id",
Parameters = new SqlParameterCollection {
new SqlParameter { Name = "@id", Value = userId }
}
};
User user = client.CreateUserQuery(database.SelfLink, query).AsEnumerable().First();
await client.DeleteUserAsync(user.SelfLink);
Console.WriteLine("Deleted user {0} from database {1}", userId, database.Id);
}
Step 7 − 먼저 SelfLink를 가져 오기 위해 쿼리 한 다음 DeleteUserAsync를 호출하여 그녀의 사용자 개체를 삭제합니다.
다음은 위의 모든 작업을 호출하는 CreateDocumentClient 작업의 구현입니다.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
ViewUsers(client);
var alice = await CreateUser(client, "Alice");
var tom = await CreateUser(client, "Tom");
ViewUsers(client);
ViewPermissions(client, alice);
ViewPermissions(client, tom);
string collectionLink = client.CreateDocumentCollectionQuery(database.SelfLink,
"SELECT VALUE c._self FROM c WHERE c.id = 'MyCollection'")
.AsEnumerable().First().Value;
await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All,
collectionLink);
await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read,
collectionLink);
ViewPermissions(client, alice);
ViewPermissions(client, tom);
await DeletePermission(client, alice, "Alice Collection Access");
await DeletePermission(client, tom, "Tom Collection Access");
await DeleteUser(client, "Alice");
await DeleteUser(client, "Tom");
}
}
위의 코드가 컴파일되고 실행되면 다음과 같은 출력이 표시됩니다.
**** View Users in myfirstdb ****
Total users in database myfirstdb: 0
**** Create User Alice in myfirstdb ****
Created new user
User ID: Alice
Resource ID: kV5oAC56NwA=
Self Link: dbs/kV5oAA==/users/kV5oAC56NwA=/
Permissions Link: dbs/kV5oAA==/users/kV5oAC56NwA=/permissions/
Timestamp: 12/17/2015 5:44:19 PM
**** Create User Tom in myfirstdb ****
Created new user
User ID: Tom
Resource ID: kV5oAALxKgA=
Self Link: dbs/kV5oAA==/users/kV5oAALxKgA=/
Permissions Link: dbs/kV5oAA==/users/kV5oAALxKgA=/permissions/
Timestamp: 12/17/2015 5:44:21 PM
**** View Users in myfirstdb ****
User #1
User ID: Tom
Resource ID: kV5oAALxKgA=
Self Link: dbs/kV5oAA==/users/kV5oAALxKgA=/
Permissions Link: dbs/kV5oAA==/users/kV5oAALxKgA=/permissions/
Timestamp: 12/17/2015 5:44:21 PM
User #2
User ID: Alice
Resource ID: kV5oAC56NwA=
Self Link: dbs/kV5oAA==/users/kV5oAC56NwA=/
Permissions Link: dbs/kV5oAA==/users/kV5oAC56NwA=/permissions/
Timestamp: 12/17/2015 5:44:19 PM
Total users in database myfirstdb: 2
**** View Permissions for Alice ****
Total permissions for Alice: 0
**** View Permissions for Tom ****
Total permissions for Tom: 0
**** Create Permission Alice Collection Access for Alice ****
Created new permission
Permission ID: Alice Collection Access
Resource ID: kV5oAC56NwDON1RduEoCAA==
Permission Mode: All
Token: type=resource&ver=1&sig=zB6hfvvleC0oGGbq5cc67w==;Zt3Lx
Ol14h8pd6/tyF1h62zbZKk9VwEIATIldw4ZyipQGW951kirueAKdeb3MxzQ7eCvDfvp7Y/ZxFpnip/D G
JYcPyim5cf+dgLvos6fUuiKSFSul7uEKqp5JmJqUCyAvD7w+qt1Qr1PmrJDyAIgbZDBFWGe2VT9FaBH o
PYwrLjRlnH0AxfbrR+T/UpWMSSHtLB8JvNFZNSH8hRjmQupuTSxCTYEC89bZ/pS6fNmNg8=;
Timestamp: 12/17/2015 5:44:28 PM
**** Create Permission Tom Collection Access for Tom ****
Created new permission
Permission ID: Tom Collection Access
Resource ID: kV5oAALxKgCMai3JKWdfAA==
Permission Mode: Read
Token: type=resource&ver=1&sig=ieBHKeyi6EY9ZOovDpe76w==;92gwq
V4AxKaCJ2dLS02VnJiig/5AEbPcfo1xvOjR10uK3a3FUMFULgsaK8nzxdz6hLVCIKUj6hvMOTOSN8Lt 7
i30mVqzpzCfe7JO3TYSJEI9D0/5HbMIEgaNJiCu0JPPwsjVecTytiLN56FHPguoQZ7WmUAhVTA0IMP6 p
jQpLDgJ43ZaG4Zv3qWJiO689balD+egwiU2b7RICH4j6R66UVye+GPxq/gjzqbHwx79t54=;
Timestamp: 12/17/2015 5:44:30 PM
**** View Permissions for Alice ****
Permission #1
Permission ID: Alice Collection Access
Resource ID: kV5oAC56NwDON1RduEoCAA==
Permission Mode: All
Token: type=resource&ver=1&sig=BSzz/VNe9j4IPJ9M31Mf4Q==;Tcq/B
X50njB1vmANZ/4aHj/3xNkghaqh1OfV95JMi6j4v7fkU+gyWe3mJasO3MJcoop9ixmVnB+RKOhFaSxE l
P37SaGuIIik7GAWS+dcEBWglMefc95L2YkeNuZsjmmW5b+a8ELCUg7N45MKbpzkp5BrmmGVJ7h4Z4pf D
rdmehYLuxSPLkr9ndbOOrD8E3bux6TgXCsgYQscpIlJHSKCKHUHfXWBP2Y1LV2zpJmRjis=;
Timestamp: 12/17/2015 5:44:28 PM
Total permissions for Alice: 1
**** View Permissions for Tom ****
Permission #1
Permission ID: Tom Collection Access
Resource ID: kV5oAALxKgCMai3JKWdfAA==
Permission Mode: Read
Token: type=resource&ver=1&sig=NPkWNJp1mAkCASE8KdR6PA==;ur/G2
V+fDamBmzECux000VnF5i28f8WRbPwEPxD1DMpFPqYcu45wlDyzT5A5gBr3/R3qqYkEVn8bU+een6Gl j
L6vXzIwsZfL12u/1hW4mJT2as2PWH3eadry6Q/zRXHAxV8m+YuxSzlZPjBFyJ4Oi30mrTXbBAEafZhA 5
yvbHkpLmQkLCERy40FbIFOzG87ypljREpwWTKC/z8RSrsjITjAlfD/hVDoOyNJwX3HRaz4=;
Timestamp: 12/17/2015 5:44:30 PM
Total permissions for Tom: 1
**** Delete Permission Alice Collection Access from Alice ****
Deleted permission Alice Collection Access from user Alice
**** Delete Permission Tom Collection Access from Tom ****
Deleted permission Tom Collection Access from user Tom
**** Delete User Alice in myfirstdb ****
Deleted user Alice from database myfirstdb
**** Delete User Tom in myfirstdb ****
Deleted user Tom from database myfirstdb
이 장에서는 DocumentDB에 저장된 데이터를 시각화하는 방법을 배웁니다. Microsoft는 데이터를 풍부한 시각적 개체로 변환하는 Power BI Desktop 도구를 제공했습니다. 또한 다양한 데이터 원본에서 데이터를 검색하고, 데이터를 병합 및 변환하고, 강력한 보고서 및 시각화를 만들고, 보고서를 Power BI에 게시 할 수 있습니다.
최신 버전의 Power BI Desktop에서 Microsoft는 이제 DocumentDB 계정에 연결할 수있는 DocumentDB에 대한 지원을 추가했습니다. 이 도구는 링크에서 다운로드 할 수 있습니다.https://powerbi.microsoft.com
지난 장에서 가져온 지진 데이터를 시각화하는 예를 살펴 보겠습니다.
Step 1 − 도구가 다운로드되면 Power BI 데스크톱을 시작합니다.
Step 2 − 외부 데이터 그룹의 홈 탭에있는 '데이터 가져 오기'옵션을 클릭하면 데이터 가져 오기 페이지가 표시됩니다.
Step 3 − Microsoft Azure DocumentDB (Beta) 옵션을 선택하고 '연결'버튼을 클릭합니다.
Step 4 − 데이터를 시각화하려는 Azure DocumentDB 계정, 데이터베이스 및 컬렉션의 URL을 입력하고 확인을 누릅니다.
이 끝점에 처음으로 연결하는 경우 계정 키를 입력하라는 메시지가 표시됩니다.
Step 5 − Azure Portal에서 사용 가능한 각 DocumentDB 계정에 고유 한 계정 키 (기본 키)를 입력 한 다음 연결을 클릭합니다.
계정이 성공적으로 연결되면 지정된 데이터베이스에서 데이터를 검색합니다. 미리보기 창에는 레코드 항목 목록이 표시되고 문서는 Power BI에서 레코드 유형으로 표시됩니다.
Step 6 − '편집'버튼을 클릭하면 쿼리 편집기가 실행됩니다.
Step 7 − Power BI 쿼리 편집기의 가운데 창에 문서 열이 표시되어야합니다. 문서 열 머리글 오른쪽에있는 확장기를 클릭하고 표시 할 열을 선택합니다.
보시다시피 위도와 경도가 별도의 열로 있지만 위도, 경도 좌표 형식으로 데이터를 시각화합니다.
Step 8 −이를 위해 '열 추가'탭을 클릭합니다.
Step 9 − 다음 페이지를 표시 할 사용자 정의 열 추가를 선택합니다.
Step 10− 새 열 이름을 지정합니다. LatLong과 위도와 경도를 쉼표로 구분 된 하나의 열에 결합하는 공식도 지정합니다. 다음은 공식입니다.
Text.From([latitude])&", "&Text.From([longitude])
Step 11 − 계속하려면 확인을 클릭하면 새 열이 추가 된 것을 볼 수 있습니다.
Step 12 − 홈 탭으로 이동하여 '닫기 및 적용'옵션을 클릭합니다.
Step 13− 보고서 캔버스에 필드를 드래그 앤 드롭하여 보고서를 생성 할 수 있습니다. 오른쪽에서 볼 수 있듯이 두 개의 창이 있습니다. 하나는 시각화 창이고 다른 하나는 필드 창입니다.
각 지진의 위치를 보여주는지도보기를 만들어 보겠습니다.
Step 14 − 시각화 창에서 맵 시각적 유형을 드래그합니다.
Step 15− 이제 필드 창에서 LatLong 필드를 시각화 창의 위치 속성으로 끌어다 놓습니다. 그런 다음 크기 필드를 Values 속성으로 끌어다 놓습니다.
Step 16 − 깊이 필드를 색 채도 속성으로 끌어다 놓습니다.
이제 각 지진의 위치를 나타내는 거품 세트를 보여주는 맵 비주얼이 표시됩니다.