DocumentDB - 快速指南


DocumentDB - 简介

在本章中,我们将简要讨论 NoSQL 和文档数据库的主要概念。我们还将快速概述 DocumentDB。

NoSQL 文档数据库

DocumentDB是微软最新的NoSQL文档数据库,那么当你说NoSQL文档数据库时,NoSQL和文档数据库到底是什么意思呢?

  • SQL是Structured Query Language的缩写,是关系型数据库的传统查询语言。SQL 通常被等同于关系数据库。

  • 将 NoSQL 数据库视为非关系型数据库确实更有帮助,因此 NoSQL 确实意味着非关系型。

有不同类型的 NoSQL 数据库,其中包括键值存储,例如 -

  • Azure 表存储。
  • 基于列的存储,例如 Cassandra。
  • NEO4 等图数据库。
  • 文档数据库,例如 MongoDB 和 Azure DocumentDB。

Azure 文档数据库

微软于2015年4月8日正式推出Azure DocumentDB ,它可以说是典型的NoSQL文档数据库。它具有大规模可扩展性,并且适用于无架构的 JSON 文档。

  • DocumentDB 是一种真正的无模式 NoSQL 文档数据库服务,专为现代移动和 Web 应用程序而设计。

  • 它还提供一致的快速读取和写入、架构灵活性以及根据需要轻松扩展和缩小数据库的能力。

  • 它不假设或要求其索引的 JSON 文档有任何架构。

  • 一旦文档被添加到数据库中,DocumentDB 就会自动索引文档中的每个属性。

  • DocumentDB 使用 SQL 语言支持复杂的即席查询,每个文档在创建后都可以立即查询,并且您可以在文档层次结构中的任何位置搜索任何属性。

DocumentDB – 定价

DocumentDB 根据数据库帐户中包含的集合数量进行计费。每个帐户可以拥有一个或多个数据库,并且每个数据库可以拥有几乎无限数量的集合,但初始默认配额为 100。可以通过联系 Azure 支持来取消此配额。

  • 集合不仅是规模单位,也是成本单位,因此在 DocumentDB 中,您按集合付费,存储容量高达 10 GB。

  • 您至少需要一个 S1 集合来将文档存储在数据库中,每月费用约为 25 美元,并根据您的 Azure 订阅进行计费。

  • 随着您的数据库大小增长并超过 10 GB,您将需要购买另一个集合来包含额外的数据。

  • 每个 S1 集合每秒将为您提供 250 个请求单位,如果这还不够,那么您可以将集合扩展到 S2,并以每月约 50 美元的价格获得每秒 1000 个请求单位。

  • 您也可以将其一直升级为 S3,每月支付约 100 美元。

DocumentDB - 优点

DocumentDB 凭借一些非常独特的功能而脱颖而出。Azure DocumentDB 提供以下关键功能和优势。

无模式

在关系数据库中,每个表都有一个架构,用于定义表中每行必须符合的列和数据类型。

相比之下,文档数据库没有定义的模式,并且每个文档都可以采用不同的结构。

SQL语法

DocumentDB 使用 SQL 语言支持复杂的即席查询,每个文档在创建后都可以立即查询。您可以搜索文档层次结构中任何位置的任何属性。

可调一致性

它提供了一些细粒度、定义明确的一致性级别,使您可以在一致性、可用性和延迟之间进行合理的权衡。

您可以从四个明确定义的一致性级别中进行选择,以实现一致性和性能之间的最佳权衡。对于查询和读取操作,DocumentDB 提供四种不同的一致性级别 -

  • 强的
  • 有界陈旧性
  • 会议
  • 最终的

弹性秤

可扩展性是 NoSQL 的核心,而 DocumentDB 提供了这一点。DocumentDB 已经证明了其规模。

  • Office OneNote 和 Xbox 等主要服务已经得到 DocumentDB 的支持,其数据库包含数十 TB 的 JSON 文档、超过一百万的活跃用户,并且以 99.95% 的可用性持续运行。

  • 随着应用程序的增长,您可以通过创建更多单元来以可预测的性能弹性扩展 DocumentDB。

完全托管

DocumentDB 可作为完全托管的基于云的平台作为在 Azure 上运行的服务。

  • 您无需安装或管理任何内容。

  • 无需处理服务器、电缆、操作系统或更新,也无需设置副本。

  • Microsoft 会完成所有这些工作并保持服务运行。

  • 只需几分钟,您只需使用浏览器和 Azure 订阅即可开始使用 DocumentDB。

DocumentDB - 环境设置

Microsoft 提供了 Visual Studio 的免费版本,其中还包含 SQL Server,可以从https://www.visualstudio.com下载

安装

步骤 1 - 下载完成后,运行安装程序。将显示以下对话框。

安装人员

步骤 2 - 单击“安装”按钮,它将开始安装过程。

安装过程

步骤 3 - 安装过程成功完成后,您将看到以下对话框。

现在重启

步骤 4 - 关闭此对话框并根据需要重新启动计算机。

步骤 5 - 现在从开始菜单打开 Visual studio,这将打开以下对话框。第一次只需要一些时间准备。

开放视觉工作室

一切完成后,您将看到 Visual Studio 的主窗口。

主窗口

步骤 6 - 让我们从文件 → 新建 → 项目创建一个新项目。

创建新项目

步骤 7 - 选择控制台应用程序,在名称字段中输入 DocumentDBDemo,然后单击确定按钮。

步骤 8 - 在解决方案资源管理器中,右键单击您的项目。

右键单击项目

步骤 9 - 选择“管理 NuGet 包”,这将在 Visual Studio 中打开以下窗口,并在“在线搜索”输入框中搜索 DocumentDB 客户端库。

管理 NuGet 包

步骤 10 - 单击安装按钮安装最新版本。

许可接受

步骤 11 - 单击“我接受”。安装完成后,您将在输出窗口中看到该消息。

开始申请

您现在可以开始申请了。

DocumentDB - 创建帐户

要使用 Microsoft Azure DocumentDB,您必须创建 DocumentDB 帐户。在本章中,我们将使用 Azure 门户创建一个 DocumentDB 帐户。

步骤 1 - 如果您已经有 Azure 订阅,请登录在线https://portal.azure.com,否则您需要先登录。

您将看到主仪表板。它是完全可定制的,因此您可以按照自己喜欢的方式排列这些图块、调整它们的大小、添加和删除经常使用或不再执行的操作的图块。

仪表板

步骤 2 - 选择页面左上角的“新建”选项。

选择新选项

步骤 3 - 现在选择数据 + 存储 > Azure DocumentDB 选项,您将看到以下“新建 DocumentDB 帐户”部分。

Azure 文档数据库

我们需要提供一个全球唯一的名称 (ID),它与 ​​.documents.azure.com 结合起来,成为我们 DocumentDB 帐户的可公开寻址的端点。我们在该帐户下创建的所有数据库都可以使用此端点通过互联网访问。

步骤 4 - 我们将其命名为 azuredocdbdemo 并单击资源组 → new_resource。

资源组

步骤 5 - 选择位置,即您希望托管此帐户的 Microsoft 数据中心。选择位置并选择您所在的区域。

选择位置

步骤 6 - 选中“固定到仪表板”复选框,然后继续并单击“创建”按钮。

创建按钮

您可以看到该图块已添加到仪表板中,它让我们知道该帐户正在创建。实际上,在 DocumentDB 分配端点、配置副本并在后台执行其他工作时,为新帐户进行设置可能需要几分钟的时间。

完成后,您将看到仪表板。

账户仪表板

步骤 7 - 现在单击创建的 DocumentDB 帐户,您将看到如下图所示的详细屏幕。

创建文档数据库

DocumentDB - 连接帐户

当您开始针对 DocumentDB 进行编程时,第一步是连接。因此,要连接到您的 DocumentDB 帐户,您需要做两件事:

  • 端点
  • 授权密钥

端点

Endpoint 是您的 DocumentDB 帐户的 URL,它是通过将您的 DocumentDB 帐户名与 .documents.azure.com 组合而成的。让我们转到仪表板。

端点

现在,单击创建的 DocumentDB 帐户。您将看到如下图所示的详细信息。

单击创建的 DocumentDB

当您选择“按键”选项时,它将显示附加信息,如下图所示。您还将看到 DocumentDB 帐户的 URL,您可以将其用作端点。

选择按键选项

授权密钥

授权密钥包含您的凭据,并且有两种类型的密钥。主密钥允许对帐户内的所有资源进行完全访问,而资源令牌则允许对特定资源进行受限访问。

万能钥匙

  • 没有什么是你用一把万能钥匙做不到的。如果需要,您可以使用主密钥清除整个数据库。

  • 因此,您绝对不想共享主密钥或将其分发到客户端环境。作为一项附加的安全措施,经常更改它是个好主意。

  • 实际上,每个数据库帐户有两个主密钥,主密钥和辅助密钥,如上面的屏幕截图中突出显示的那样。

资源代币

  • 您还可以使用资源令牌代替主密钥。

  • 基于资源令牌的连接只能访问该令牌指定的资源,不能访问其他资源。

  • 资源令牌基于用户权限,因此首先您创建一个或多个用户,这些用户是在数据库级别定义的。

  • 您可以根据您希望允许每个用户访问的资源为每个用户创建一个或多个权限。

  • 每个权限都会生成一个资源令牌,该令牌允许对给定资源进行只读或完全访问,并且可以是数据库中的任何用户资源。

让我们转到第 3 章中创建的控制台应用程序。

步骤 1 - 在 Program.cs 文件中添加以下引用。

using Microsoft.Azure.Documents; 
using Microsoft.Azure.Documents.Client; 
using Microsoft.Azure.Documents.Linq; 
using Newtonsoft.Json;

步骤 2 - 现在添加端点 URL 和授权密钥。在此示例中,我们将使用主键作为授权键。

请注意,在您的情况下,端点 URL 和授权密钥应该不同。

private const string EndpointUrl = "https://azuredocdbdemo.documents.azure.com:443/"; 
private const string AuthorizationKey = 
   "BBhjI0gxdVPdDbS4diTjdloJq7Fp4L5RO/StTt6UtEufDM78qM2CtBZWbyVwFPSJIm8AcfDu2O+AfV T+TYUnBQ==";

步骤 3 - 在名为 CreateDocumentClient 的异步任务中创建 DocumentClient 的新实例,并实例化新的 DocumentClient。

步骤 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 类的实例。

DocumentDB - 创建数据库

在本章中,我们将学习如何创建数据库。要使用 Microsoft Azure DocumentDB,您必须拥有 DocumentDB 帐户、数据库、集合和文档。我们已经有一个 DocumentDB 帐户,现在要创建数据库,我们有两个选择 -

  • Microsoft Azure 门户或
  • .Net SDK

使用 Microsoft Azure 门户为 DocumentDB 创建数据库

要使用门户创建数据库,请执行以下步骤。

步骤 1 - 登录 Azure 门户,您将看到仪表板。

登录门户

步骤 2 - 现在单击创建的 DocumentDB 帐户,您将看到详细信息,如以下屏幕截图所示。

单击创建的 DocumentDB

步骤 3 - 选择“添加数据库”选项并提供数据库的 ID。

选择添加数据库

步骤 4 - 单击“确定”。

数据库已添加

可以看到数据库已添加。目前,它没有集合,但我们可以稍后添加集合,它们是存储 JSON 文档的容器。请注意,它同时具有 ID 和资源 ID。

使用 .Net SDK 为 DocumentDB 创建数据库

要使用 .Net SDK 创建数据库,请执行以下步骤。

步骤 1 - 在 Visual Studio 中打开上一章的控制台应用程序。

步骤 2 - 通过创建新的数据库对象来创建新数据库。要创建新数据库,我们只需分配 Id 属性,我们在 CreateDatabase 任务中将其设置为“mynewdb”。

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 *******"); 
} 

步骤 3 - 现在将此数据库定义传递给 CreateDatabaseAsync,并使用 Resource 属性返回结果。所有创建对象方法都会返回一个 Resource 属性,该属性描述所创建的项目,在本例中是一个数据库。

我们从 Resource 属性获取新的数据库对象,并将其与 DocumentDB 分配给它的资源 ID 一起显示在控制台上。

步骤 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 - 列出数据库

到目前为止,我们已经在 DocumentDB 帐户中创建了两个数据库,第一个数据库是使用 Azure 门户创建的,第二个数据库是使用 .Net SDK 创建的。现在要查看这些数据库,您可以使用 Azure 门户。

转到 Azure 门户上的 DocumentDB 帐户,您现在将看到两个数据库。

两个数据库

您还可以使用 .Net SDK 从代码中查看或列出数据库。以下是所涉及的步骤。

步骤 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() 的调用。

步骤 2 - 实例化 DocumentClient 后,从 CreateDocumentClient 任务中调用 GetDatabases 方法。

步骤 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 和资源 ID。最后您还将看到数据库的总数。

******** Get Databases List ******** 
 Database Id: myfirstdb; Rid: Ic8LAA== 
 Database Id: mynewdb; Rid: ltpJAA==  
Total databases: 2 

DocumentDB - 删除数据库

您可以使用 .Net SDK 从门户以及代码中删除一个或多个数据库。在这里,我们将逐步讨论如何删除 DocumentDB 中的数据库。

步骤 1 - 转到 Azure 门户上的 DocumentDB 帐户。为了演示的目的,我添加了两个数据库,如下面的屏幕截图所示。

删除数据库

步骤 2 - 要删除任何数据库,您需要单击该数据库。让我们选择tempdb,您将看到以下页面,选择“删除数据库”选项。

删除数据库

步骤 3 - 它将显示确认消息,现在单击“是”按钮。

确认信息

您将看到仪表板中不再提供 tempdb。

临时数据库已删除

您还可以使用 .Net SDK 从代码中删除数据库。执行以下操作步骤。

步骤 1 - 让我们通过指定要删除的数据库的 ID 来删除数据库,但我们需要其 SelfLink。

步骤 2 - 我们像以前一样调用 CreateDatabaseQuery,但这次我们实际上提供一个查询来仅返回 ID 为 tempdb1 的一个数据库。

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);
}

步骤 3 - 这次,我们可以调用 AsEnumerable 而不是 ToList(),因为我们实际上不需要列表对象。只期望结果,调用 AsEnumerable 就足够了,这样我们就可以使用 First() 获取查询返回的第一个数据库对象。这是 tempdb1 的数据库对象,它有一个 SelfLink,我们可以使用它来调用删除数据库的 DeleteDatabaseAsync。

步骤 4 - 在实例化 DocumentClient 后,您还需要从 CreateDocumentClient 任务调用 DeleteDatabase 任务。

步骤 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帐户中只剩下两个数据库。

DocumentDB - 创建集合

在本章中,我们将学习如何创建集合。这与创建数据库类似。您可以从门户或使用 .Net SDK 的代码创建集合。

步骤 1 - 转到 Azure 门户上的主仪表板。

创建收藏

步骤 2 - 从数据库列表中选择 myfirstdb。

我的第一个数据库

步骤 3 - 单击“添加集合”选项并指定集合 ID。选择不同选项的定价层。

添加收藏

步骤 4 - 让我们选择 S1 Standard 并单击 Select → OK 按钮。

选择S1标准

如您所见,MyCollection 已添加到 myfirstdb 中。

您还可以使用 .Net SDK 从代码创建集合。让我们看一下从代码中添加集合的以下步骤。

步骤 1 - 在 Visual Studio 中打开控制台应用程序。

步骤 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);
}

我们创建一个新的 DocumentCollection 对象,该对象使用 CreateDocumentCollectionAsync 方法所需的 Id 定义新集合,该方法还接受一个选项参数,我们在此处使用该参数来设置新集合的性能层(我们将其称为 OfferType)。

默认为 S1,并且由于我们没有传入 OfferType,因此对于 MyCollection1,这将是一个 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

DocumentDB - 删除集合

要删除一个或多个集合,您可以从门户以及使用 .Net SDK 的代码中执行相同的操作。

步骤 1 - 转到 Azure 门户上的 DocumentDB 帐户。为了演示的目的,我添加了另外两个集合,如下面的屏幕截图所示。

删除集合

步骤 2 - 要删除任何集合,您需要单击该集合。我们选择 TempCollection1。您将看到以下页面,选择“删除集合”选项。

选择系列

步骤 3 - 它将显示确认消息。现在单击“是”按钮。

删除收藏留言

您将看到 TempCollection1 在仪表板上不再可用。

收藏已删除

您还可以使用 .Net SDK 从代码中删除集合。为此,请执行以下步骤。

步骤 1 - 让我们通过指定要删除的集合的 ID 来删除集合。

这是通过 Id 查询来获取删除资源所需的 selfLink 的常见模式。

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 进行硬编码,因此此方法可用于删除任何集合。我们通过 Id 查询特定集合,其中 Id 参数在此 SqlParameterCollection 中定义,并分配给此 SqlQuerySpec 的参数属性。

然后,SDK 会为 DocumentDB 构建最终查询字符串,并将 collectionId 嵌入其中。

步骤 2 - 运行查询,然后使用其 SelfLink 从 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

DocumentDB - 插入文档

在本章中,我们将开始使用集合中的实际文档。您可以使用 Azure 门户或 .Net SDK 创建文档。

使用 Azure 门户创建文档

让我们看一下将文档添加到集合中的以下步骤。

步骤 1 - 在 myfirstdb 中添加 S1 定价层的新集合系列。

插入文档

步骤 2 - 选择“家庭”集合,然后单击“创建文档”选项以打开“新建文档”边栏选项卡。

家庭系列

这只是一个简单的文本编辑器,可让您为新文档键入任何 JSON。

简单的文本编辑器

步骤 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,但它也有嵌套属性。

例如,parents 属性作为 JSON 数组提供,如方括号所示。我们还有另一个子数组,即使本例中数组中只有一个子数组。

步骤 4 - 单击“保存”按钮保存文档,我们已经创建了第一个文档。

正如您所看到的,我们的 JSON 应用了漂亮的格式,它将每个属性分解在自己的行上,并用空格缩进以传达每个属性的嵌套级别。

保存文档

该门户包括一个文档资源管理器,因此我们现在使用它来检索我们刚刚创建的文档。

检索文件

步骤 5 - 选择一个数据库和数据库中的任何集合以查看该集合中的文档。目前,我们只有一个名为 myfirstdb 的数据库和一个名为 Families 的集合,这两个数据库都已在下拉列表中预先选择。

选择一个数据库

默认情况下,文档资源管理器显示集合中未过滤的文档列表,但您也可以按 ID 搜索任何特定文档或基于部分 ID 的通配符搜索来搜索多个文档。

到目前为止,我们的收藏中只有一份文档,我们在接下来的屏幕上看到它的 ID:AndersonFamily。

步骤 6 - 单击 ID 以查看文档。

点击身份证

使用 .NET SDK 创建文档

如您所知,文档只是另一种类型的资源,并且您已经熟悉如何使用 SDK 处理资源。

  • 当然,文档和其他资源之间的一大区别是它们是无模式的。

  • 因此有很多选择。当然,您可以只使用 JSON 对象图,甚至可以使用 JSON 文本的原始字符串,但您也可以使用动态对象,这样您就可以在运行时绑定到属性,而无需在编译时定义类。

  • 您还可以使用真正的 C# 对象或所谓的实体,它们可能是您的业务域类。

让我们开始使用.Net SDK 创建文档。以下是步骤。

步骤 1 - 实例化 DocumentClient,然后我们将查询 myfirstdb 数据库,然后查询 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); 
   } 
}

步骤 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; 
}

步骤 3 - 这次我们调用 CreateDocumentAsync 指定我们要将文档添加到的集合的 SelfLink。我们收到带有资源属性的响应,在本例中,该资源属性代表新文档及其系统生成的属性。

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 为我们的新文档生成了这个 Id。

DocumentDB - 查询文档

在DocumentDB中,我们实际上使用SQL来查询文档,因此本章主要讲述使用DocumentDB中特殊的SQL语法进行查询。不过,如果您正在进行 .NET 开发,还可以使用 LINQ 提供程序,它可以从 LINQ 查询生成适当的 SQL。

使用Portal查询文档

Azure 门户有一个查询资源管理器,可让你针对 DocumentDB 数据库运行任何 SQL 查询。

我们将使用查询资源管理器从最简单的查询开始,演示查询语言的许多不同功能和特性。

步骤 1 - 在数据库边栏选项卡中,单击以打开“查询资源管理器”边栏选项卡。

查询浏览器刀片

请记住,查询在集合范围内运行,因此查询资源管理器允许您在此下拉列表中选择集合。

运行查询

步骤 2 - 选择之前使用门户创建的家庭集合。

查询资源管理器将打开这个简单的查询 SELECT * FROM c,它只是从集合中检索所有文档。

步骤 3 - 通过单击“运行查询”按钮执行此查询。然后您将看到在“结果”边栏选项卡中检索到完整的文档。

结果刀片中的文档

使用.Net SDK查询文档

以下是使用 .Net SDK 运行一些文档查询的步骤。

在此示例中,我们要查询刚刚添加的新创建的文档。

步骤 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,这会根据需要发出尽可能多的请求,以在一行代码中提取所有结果。

步骤 2 - 相反,调用 AsDocumentQuery,此方法返回具有 HasMoreResults 属性的查询对象。

步骤 3 - 如果 HasMoreResults 为 true,则调用 ExecuteNextAsync 获取下一个块,然后转储该块的所有内容。

步骤 4 - 如果您愿意,您还可以使用 LINQ 而不是 SQL 进行查询。在这里,我们在 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 子句

步骤 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

DocumentDB - 更新文档

在本章中,我们将学习如何更新文档。使用 Azure 门户,您可以通过在文档资源管理器中打开文档并在编辑器中像文本文件一样更新它来轻松更新文档。

更新文档

单击“保存”按钮。现在,当您需要使用 .Net SDK 更改文档时,只需替换它即可。您不需要删除并重新创建它,这除了乏味之外,还会更改资源 ID,而当您只是修改文档时,您不会希望这样做。以下是使用 .Net SDK 更新文档的以下步骤。

让我们看一下下面的 ReplaceDocuments 任务,我们将查询 isNew 属性为 true 的文档,但我们不会得到任何结果,因为没有任何文档。因此,让我们修改之前添加的文档,即名称以 New Customer 开头的文档。

步骤 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 'i