DocumentDB - Guide rapide

Dans ce chapitre, nous discuterons brièvement des principaux concepts relatifs à NoSQL et aux bases de données documentaires. Nous aurons également un aperçu rapide de DocumentDB.

Base de données de documents NoSQL

DocumentDB est la dernière base de données de documents NoSQL de Microsoft, alors quand vous parlez de base de données de documents NoSQL, qu'entendons-nous précisément par NoSQL et base de données de documents?

  • SQL signifie langage de requête structuré qui est le langage de requête traditionnel des bases de données relationnelles. SQL est souvent assimilé à des bases de données relationnelles.

  • Il est vraiment plus utile de considérer une base de données NoSQL comme une base de données non relationnelle, donc NoSQL signifie vraiment non relationnelle.

Il existe différents types de bases de données NoSQL qui incluent des magasins de valeurs clés tels que -

  • Stockage de table Azure.
  • Magasins basés sur des colonnes comme Cassandra.
  • Bases de données graphiques comme NEO4.
  • Documentez les bases de données comme MongoDB et Azure DocumentDB.

Azure DocumentDB

Microsoft a lancé officiellement Azure DocumentDB le 8 Avril e 2015, et il peut certainement être considérée comme une base de données de documents NoSQL typique. Il est extrêmement évolutif et fonctionne avec des documents JSON sans schéma.

  • DocumentDB est un véritable service de base de données de documents NoSQL sans schéma conçu pour les applications mobiles et Web modernes.

  • Il offre également des lectures et des écritures toujours rapides, une flexibilité de schéma et la possibilité de faire évoluer facilement une base de données à la demande.

  • Il n'assume ni ne requiert de schéma pour les documents JSON qu'il indexe.

  • DocumentDB indexe automatiquement chaque propriété d'un document dès que le document est ajouté à la base de données.

  • DocumentDB permet des requêtes ad hoc complexes à l'aide d'un langage SQL, et chaque document est instantanément interrogeable au moment de sa création, et vous pouvez rechercher sur n'importe quelle propriété n'importe où dans la hiérarchie des documents.

DocumentDB - Tarifs

DocumentDB est facturé en fonction du nombre de collections contenues dans un compte de base de données. Chaque compte peut avoir une ou plusieurs bases de données et chaque base de données peut avoir un nombre pratiquement illimité de collections, bien qu'il existe un quota initial par défaut de 100. Ce quota peut être levé en contactant le support Azure.

  • Une collection n'est pas seulement une unité d'échelle, mais aussi une unité de coût, donc dans DocumentDB, vous payez par collection, qui a une capacité de stockage allant jusqu'à 10 Go.

  • Au minimum, vous aurez besoin d'une collection S1 pour stocker des documents dans une base de données qui coûtera environ 25 $ par mois, qui sera facturée sur votre abonnement Azure.

  • À mesure que la taille de votre base de données augmente et dépasse 10 Go, vous devrez acheter une autre collection pour contenir les données supplémentaires.

  • Chaque collection S1 vous donnera 250 unités de demande par seconde, et si cela ne suffit pas, vous pouvez faire évoluer la collection jusqu'à un S2 et obtenir 1000 unités de demande par seconde pour environ 50 $ par mois.

  • Vous pouvez également le transformer en un S3 et payer environ 100 $ par mois.

DocumentDB se distingue par des capacités tout à fait uniques. Azure DocumentDB offre les fonctionnalités et avantages clés suivants.

Sans schéma

Dans une base de données relationnelle, chaque table a un schéma qui définit les colonnes et les types de données auxquels chaque ligne de la table doit se conformer.

En revanche, une base de données de documents n'a pas de schéma défini et chaque document peut être structuré différemment.

Syntaxe SQL

DocumentDB permet des requêtes ad hoc complexes en utilisant le langage SQL, et chaque document est instantanément interrogeable dès sa création. Vous pouvez rechercher n'importe quelle propriété n'importe où dans la hiérarchie du document.

Cohérence accordable

Il fournit des niveaux de cohérence granulaires et bien définis, ce qui vous permet de faire des compromis judicieux entre cohérence, disponibilité et latence.

Vous pouvez choisir parmi quatre niveaux de cohérence bien définis pour obtenir un compromis optimal entre cohérence et performances. Pour les requêtes et les opérations de lecture, DocumentDB propose quatre niveaux de cohérence distincts:

  • Strong
  • Bounded-staleness
  • Session
  • Eventual

Échelle élastique

L'évolutivité est le nom du jeu avec NoSQL, et DocumentDB offre. DocumentDB a déjà fait ses preuves.

  • Les principaux services comme Office OneNote et Xbox sont déjà soutenus par DocumentDB avec des bases de données contenant des dizaines de téraoctets de documents JSON, plus d'un million d'utilisateurs actifs et fonctionnant de manière cohérente avec une disponibilité de 99,95%.

  • Vous pouvez mettre à l'échelle DocumentDB de manière élastique avec des performances prévisibles en créant davantage d'unités à mesure que votre application se développe.

Entièrement géré

DocumentDB est disponible en tant que plate-forme cloud entièrement gérée en tant que service s'exécutant sur Azure.

  • Il n'y a tout simplement rien à installer ou à gérer.

  • Il n'y a pas de serveurs, de câbles, de systèmes d'exploitation ou de mises à jour à gérer, pas de répliques à configurer.

  • Microsoft fait tout ce travail et maintient le service en marche.

  • En quelques minutes, vous pouvez commencer à travailler avec DocumentDB en utilisant simplement un navigateur et un abonnement Azure.

Microsoft fournit une version gratuite de Visual Studio qui contient également SQL Server et peut être téléchargée à partir de https://www.visualstudio.com

Installation

Step 1- Une fois le téléchargement terminé, exécutez le programme d'installation. La boîte de dialogue suivante s'affiche.

Step 2 - Cliquez sur le bouton Installer et il lancera le processus d'installation.

Step 3 - Une fois le processus d'installation terminé, vous verrez la boîte de dialogue suivante.

Step 4 - Fermez cette boîte de dialogue et redémarrez votre ordinateur si nécessaire.

Step 5- Maintenant, ouvrez Visual Studio à partir du menu Démarrer qui ouvrira la boîte de dialogue ci-dessous. Cela prendra du temps pour la première fois uniquement pour la préparation.

Une fois que tout est fait, vous verrez la fenêtre principale de Visual Studio.

Step 6 - Créons un nouveau projet à partir de Fichier → Nouveau → Projet.

Step 7 - Sélectionnez Application console, saisissez DocumentDBDemo dans le champ Nom et cliquez sur le bouton OK.

Step 8 - Dans l'Explorateur de solutions, cliquez avec le bouton droit sur votre projet.

Step 9 - Sélectionnez Gérer les packages NuGet qui ouvrira la fenêtre suivante dans Visual Studio et dans la zone de saisie Rechercher en ligne, recherchez DocumentDB Client Library.

Step 10 - Installez la dernière version en cliquant sur le bouton Installer.

Step 11- Cliquez sur «J'accepte». Une fois l'installation terminée, vous verrez le message dans votre fenêtre de sortie.

Vous êtes maintenant prêt à démarrer votre application.

Pour utiliser Microsoft Azure DocumentDB, vous devez créer un compte DocumentDB. Dans ce chapitre, nous allons créer un compte DocumentDB à l'aide du portail Azure.

Step 1 - Connectez-vous en ligne https://portal.azure.com si vous avez déjà un abonnement Azure, sinon vous devez d'abord vous connecter.

Vous verrez le tableau de bord principal. Il est entièrement personnalisable afin que vous puissiez organiser ces vignettes comme vous le souhaitez, les redimensionner, ajouter et supprimer des vignettes pour les choses que vous utilisez fréquemment ou que vous ne faites plus.

Step 2 - Sélectionnez l'option «Nouveau» en haut à gauche de la page.

Step 3 - Sélectionnez maintenant l'option Données + Stockage> Azure DocumentDB et vous voyez la section Nouveau compte DocumentDB suivante.

Nous devons trouver un nom (ID) unique au monde, qui, combiné à .documents.azure.com, est le point de terminaison publiquement adressable à notre compte DocumentDB. Toutes les bases de données que nous créons sous ce compte sont accessibles sur Internet à l'aide de ce point de terminaison.

Step 4 - Appelons-le azuredocdbdemo et cliquez sur Resource Group → new_resource.

Step 5- Choisissez l'emplacement, c'est-à-dire dans quel centre de données Microsoft vous souhaitez que ce compte soit hébergé. Sélectionnez l'emplacement et choisissez votre région.

Step 6 - Cochez la case Épingler au tableau de bord et continuez et cliquez sur le bouton Créer.

Vous pouvez voir que la vignette a déjà été ajoutée au tableau de bord et qu'elle nous informe que le compte est en cours de création. La configuration d'un nouveau compte peut prendre quelques minutes pendant que DocumentDB alloue le point de terminaison, provisionne les répliques et effectue d'autres tâches en arrière-plan.

Une fois cela fait, vous verrez le tableau de bord.

Step 7 - Cliquez maintenant sur le compte DocumentDB créé et vous verrez un écran détaillé comme l'image suivante.

Lorsque vous commencez à programmer avec DocumentDB, la toute première étape consiste à vous connecter. Donc, pour vous connecter à votre compte DocumentDB, vous aurez besoin de deux choses;

  • Endpoint
  • Clé d'autorisation

Point final

Endpoint est l'URL de votre compte DocumentDB et il est construit en combinant le nom de votre compte DocumentDB avec .documents.azure.com. Allons au tableau de bord.

Maintenant, cliquez sur le compte DocumentDB créé. Vous verrez les détails comme indiqué dans l'image suivante.

Lorsque vous sélectionnez l'option «Clés», il affichera des informations supplémentaires comme indiqué dans l'image suivante. Vous verrez également l'URL de votre compte DocumentDB, que vous pouvez utiliser comme point de terminaison.

Clé d'autorisation

La clé d'autorisation contient vos informations d'identification et il existe deux types de clés. La clé principale permet un accès complet à toutes les ressources du compte, tandis que les jetons de ressources permettent un accès restreint à des ressources spécifiques.

Clés principales

  • Vous ne pouvez rien faire avec une clé principale. Vous pouvez exploser toute votre base de données si vous le souhaitez, en utilisant la clé principale.

  • Pour cette raison, vous ne voulez certainement pas partager la clé principale ou la distribuer aux environnements clients. Comme mesure de sécurité supplémentaire, il est judicieux de le changer fréquemment.

  • Il existe en fait deux clés principales pour chaque compte de base de données, la principale et la secondaire, comme indiqué dans la capture d'écran ci-dessus.

Jetons de ressources

  • Vous pouvez également utiliser des jetons de ressources au lieu d'une clé principale.

  • Les connexions basées sur des jetons de ressources peuvent uniquement accéder aux ressources spécifiées par les jetons et aucune autre ressource.

  • Les jetons de ressources sont basés sur les autorisations des utilisateurs, vous devez donc d'abord créer un ou plusieurs utilisateurs, et ceux-ci sont définis au niveau de la base de données.

  • Vous créez une ou plusieurs autorisations pour chaque utilisateur, en fonction des ressources auxquelles vous souhaitez autoriser chaque utilisateur à accéder.

  • Chaque autorisation génère un jeton de ressource qui permet un accès en lecture seule ou complet à une ressource donnée et qui peut être n'importe quelle ressource utilisateur dans la base de données.

Passons à l'application console créée au chapitre 3.

Step 1 - Ajoutez les références suivantes dans le fichier Program.cs.

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

Step 2- Ajoutez maintenant l'URL du point de terminaison et la clé d'autorisation. Dans cet exemple, nous utiliserons la clé primaire comme clé d'autorisation.

Notez que dans votre cas, l'URL du point de terminaison et la clé d'autorisation doivent être différentes.

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

Step 3 - Créez une nouvelle instance de DocumentClient dans une tâche asynchrone appelée CreateDocumentClient et instanciez un nouveau DocumentClient.

Step 4 - Appelez votre tâche asynchrone à partir de votre méthode Main.

Voici le fichier Program.cs complet à ce jour.

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

Dans ce chapitre, nous avons appris à se connecter à un compte DocumentDB et à créer une instance de la classe DocumentClient.

Dans ce chapitre, nous allons apprendre à créer une base de données. Pour utiliser Microsoft Azure DocumentDB, vous devez disposer d'un compte DocumentDB, d'une base de données, d'une collection et de documents. Nous avons déjà un compte DocumentDB, maintenant pour créer une base de données, nous avons deux options -

  • Portail Microsoft Azure ou
  • SDK .Net

Créer une base de données pour DocumentDB à l'aide du portail Microsoft Azure

Pour créer une base de données à l'aide du portail, procédez comme suit.

Step 1 - Connectez-vous au portail Azure et vous verrez le tableau de bord.

Step 2 - Cliquez maintenant sur le compte DocumentDB créé et vous verrez les détails comme indiqué dans la capture d'écran suivante.

Step 3 - Sélectionnez l'option Ajouter une base de données et fournissez l'ID de votre base de données.

Step 4 - Cliquez sur OK.

Vous pouvez voir que la base de données est ajoutée. Pour le moment, il n'a pas de collection, mais nous pouvons ajouter des collections plus tard qui sont les conteneurs qui vont stocker nos documents JSON. Notez qu'il a à la fois un ID et un ID de ressource.

Créer une base de données pour DocumentDB à l'aide du SDK .Net

Pour créer une base de données à l'aide du SDK .Net, procédez comme suit.

Step 1 - Ouvrez l'application console dans Visual Studio à partir du dernier chapitre.

Step 2- Créez la nouvelle base de données en créant un nouvel objet de base de données. Pour créer une nouvelle base de données, il suffit d'attribuer la propriété Id, que nous définissons sur «mynewdb» dans une tâche CreateDatabase.

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- Passez maintenant cette définition de base de données à CreateDatabaseAsync et récupérez un résultat avec une propriété Resource. Toutes les méthodes de création d'objet renvoient une propriété Resource qui décrit l'élément qui a été créé, qui est une base de données dans ce cas.

Nous obtenons le nouvel objet de base de données à partir de la propriété Resource et il est affiché sur la console avec l'ID de ressource que DocumentDB lui a attribué.

Step 4 - Appelez maintenant la tâche CreateDatabase à partir de la tâche CreateDocumentClient une fois que DocumentClient est instancié.

using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { 
   await CreateDatabase(client); 
}

Voici le fichier Program.cs complet à ce jour.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante qui contient les ID de base de données et de ressources.

******** Create Database ******* 
 Database Id: mynewdb; Rid: ltpJAA== 
******** Database Created *******

Jusqu'à présent, nous avons créé deux bases de données dans notre compte DocumentDB, la première est créée à l'aide du portail Azure tandis que la seconde est créée à l'aide du SDK .Net. Maintenant, pour afficher ces bases de données, vous pouvez utiliser le portail Azure.

Accédez à votre compte DocumentDB sur le portail Azure et vous verrez maintenant deux bases de données.

Vous pouvez également afficher ou répertorier les bases de données à partir de votre code à l'aide du SDK .Net. Voici les étapes impliquées.

Step 1 - Émettez une requête de base de données sans paramètres qui renvoie une liste complète, mais vous pouvez également transmettre une requête pour rechercher une base de données spécifique ou des bases de données spécifiques.

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

Vous verrez qu'il existe un tas de ces méthodes CreateQuery pour localiser des collections, des documents, des utilisateurs et d'autres ressources. Ces méthodes n'exécutent pas réellement la requête, elles définissent simplement la requête et renvoient un objet itératif.

C'est l'appel à ToList () qui exécute réellement la requête, itère les résultats et les renvoie dans une liste.

Step 2 - Appelez la méthode GetDatabases à partir de la tâche CreateDocumentClient une fois DocumentClient instancié.

Step 3 - Vous devez également commenter la tâche CreateDatabase ou modifier l'ID de la base de données, sinon vous obtiendrez un message d'erreur indiquant que la base de données existe.

using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
   //await CreateDatabase(client); 
   GetDatabases(client); 
}

Voici le fichier Program.cs complet à ce jour.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante qui contient les ID de base de données et de ressources des deux bases de données. À la fin, vous verrez également le nombre total de bases de données.

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

Vous pouvez supprimer une ou plusieurs bases de données à partir du portail ainsi qu'à partir du code à l'aide du SDK .Net. Ici, nous allons discuter, par étapes, comment supprimer une base de données dans DocumentDB.

Step 1- Accédez à votre compte DocumentDB sur le portail Azure. À des fins de démonstration, j'ai ajouté deux autres bases de données, comme le montre la capture d'écran suivante.

Step 2- Pour supprimer une base de données, vous devez cliquer sur cette base de données. Sélectionnons tempdb, vous verrez la page suivante, sélectionnez l'option «Supprimer la base de données».

Step 3 - Il affichera le message de confirmation, cliquez maintenant sur le bouton «Oui».

Vous verrez que tempdb n'est plus disponible dans votre tableau de bord.

Vous pouvez également supprimer des bases de données de votre code à l'aide du SDK .Net. Voici les étapes à suivre.

Step 1 - Supprimons la base de données en spécifiant l'ID de la base de données que nous voulons supprimer, mais nous avons besoin de son SelfLink.

Step 2 - Nous appelons CreateDatabaseQuery comme auparavant, mais cette fois, nous fournissons en fait une requête pour ne renvoyer qu'une seule base de données avec l'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);
}

Step 3- Cette fois, nous pouvons appeler AsEnumerable au lieu de ToList () car nous n'avons pas réellement besoin d'un objet de liste. En attendant seulement le résultat, appeler AsEnumerable est suffisant pour que nous puissions obtenir le premier objet de base de données retourné par la requête avec First (). Il s'agit de l'objet de base de données pour tempdb1 et il a un SelfLink que nous pouvons utiliser pour appeler DeleteDatabaseAsync qui supprime la base de données.

Step 4 - Vous devez également appeler la tâche DeleteDatabase à partir de la tâche CreateDocumentClient après l'instanciation de DocumentClient.

Step 5 - Pour afficher la liste des bases de données après avoir supprimé la base de données spécifiée, appelons à nouveau la méthode GetDatabases.

using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
   //await CreateDatabase(client);
	
   GetDatabases(client);
   await DeleteDatabase(client);
   GetDatabases(client); 
}

Voici le fichier Program.cs complet à ce jour.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante qui contient les ID de base de données et de ressources des trois bases de données et le nombre total de bases de données.

******** 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

Après avoir supprimé la base de données, vous verrez également à la fin qu'il ne reste que deux bases de données dans le compte DocumentDB.

Dans ce chapitre, nous allons apprendre à créer une collection. C'est similaire à la création d'une base de données. Vous pouvez créer une collection à partir du portail ou à partir du code à l'aide du SDK .Net.

Step 1 - Accédez au tableau de bord principal sur le portail Azure.

Step 2 - Sélectionnez myfirstdb dans la liste des bases de données.

Step 3- Cliquez sur l'option «Ajouter une collection» et spécifiez l'ID de la collection. Sélectionnez le niveau de tarification pour une option différente.

Step 4 - Sélectionnez S1 Standard et cliquez sur le bouton Sélectionner → OK.

Comme vous pouvez le voir, MyCollection est ajouté au myfirstdb.

Vous pouvez également créer une collection à partir du code à l'aide du SDK .Net. Jetons un coup d'œil aux étapes suivantes pour ajouter des collections à partir du code.

Step 1 - Ouvrez l'application Console dans Visual Studio.

Step 2 - Pour créer une collection, récupérez d'abord la base de données myfirstdb par son ID dans la tâche 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 CreateCollection(client, "MyCollection1");
      await CreateCollection(client, "MyCollection2", "S2"); 
   }
}

Voici l'implémentation de la tâche 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);
}

Nous créons un nouvel objet DocumentCollection qui définit la nouvelle collection avec l'ID souhaité pour la méthode CreateDocumentCollectionAsync qui accepte également un paramètre d'options que nous utilisons ici pour définir le niveau de performance de la nouvelle collection, que nous appelons offerType.

Par défaut, S1 et comme nous n'avons pas passé de offerType, pour MyCollection1, ce sera donc une collection S1 et pour MyCollection2, nous avons passé S2 qui en fait un S2 comme indiqué ci-dessus.

Voici l'implémentation de la méthode 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);
}

Voici l'implémentation complète du fichier program.cs pour les collections.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante qui contient toutes les informations relatives à la collection.

**** 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

Pour supprimer une ou plusieurs collections, vous pouvez faire de même à partir du portail ainsi qu'à partir du code à l'aide du SDK .Net.

Step 1- Accédez à votre compte DocumentDB sur le portail Azure. À des fins de démonstration, j'ai ajouté deux autres collections, comme le montre la capture d'écran suivante.

Step 2- Pour supprimer une collection, vous devez cliquer sur cette collection. Choisissons TempCollection1. Vous verrez la page suivante, sélectionnez l'option «Supprimer la collection».

Step 3- Il affichera le message de confirmation. Cliquez maintenant sur le bouton «Oui».

Vous verrez que TempCollection1 n'est plus disponible sur votre tableau de bord.

Vous pouvez également supprimer des collections de votre code à l'aide du SDK .Net. Pour ce faire, voici les étapes suivantes.

Step 1 - Supprimons la collection en spécifiant l'ID de la collection que nous voulons supprimer.

C'est le modèle habituel d'interrogation par Id pour obtenir les selfLinks nécessaires pour supprimer une ressource.

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

Nous voyons ici la manière préférée de construire une requête paramétrée. Nous ne codons pas en dur la collectionId, donc cette méthode peut être utilisée pour supprimer n'importe quelle collection. Nous recherchons une collection spécifique par Id où le paramètre Id est défini dans ce SqlParameterCollection affecté à la propriété du paramètre de ce SqlQuerySpec.

Ensuite, le SDK effectue le travail de construction de la chaîne de requête finale pour DocumentDB avec l'ID de collection incorporé à l'intérieur.

Step 2 - Exécutez la requête, puis utilisez son SelfLink pour supprimer la collection de la tâche 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"); 
   } 
}

Voici l'implémentation complète du fichier 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); 
      }
		
   } 
}

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** Delete Collection TempCollection in myfirstdb **** 
Deleted collection TempCollection from database myfirstdb

Dans ce chapitre, nous allons travailler avec des documents réels dans une collection. Vous pouvez créer des documents à l'aide du portail Azure ou du SDK .Net.

Création de documents avec le portail Azure

Jetons un coup d'œil aux étapes suivantes pour ajouter un document à votre collection.

Step 1 - Ajouter une nouvelle collection Familles de niveau tarifaire S1 dans myfirstdb.

Step 2 - Sélectionnez la collection Familles et cliquez sur l'option Créer un document pour ouvrir le panneau Nouveau document.

Ceci est juste un simple éditeur de texte qui vous permet de taper n'importe quel JSON pour un nouveau document.

Step 3 - Comme il s'agit de saisie de données brutes, entrons dans notre premier document.

{
   "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
}

Lorsque vous entrez le document ci-dessus, vous verrez l'écran suivant.

Notez que nous avons fourni un identifiant pour le document. La valeur id est toujours requise et doit être unique dans tous les autres documents de la même collection. Lorsque vous le laissez de côté, DocumentDB en génère automatiquement un pour vous à l'aide d'un GUID ou d'un identifiant global unique.

L'identifiant est toujours une chaîne et il ne peut pas s'agir d'un nombre, d'une date, d'un booléen ou d'un autre objet, et il ne peut pas comporter plus de 255 caractères.

Notez également la structure hiérarchique du document qui a quelques propriétés de premier niveau comme l'id requis, ainsi que lastName et isRegistered, mais il a également des propriétés imbriquées.

Par exemple, la propriété parents est fournie sous forme de tableau JSON comme indiqué par les crochets. Nous avons également un autre tableau pour les enfants, même s'il n'y a qu'un seul enfant dans le tableau dans cet exemple.

Step 4 - Cliquez sur le bouton «Enregistrer» pour enregistrer le document et nous avons créé notre premier document.

Comme vous pouvez le voir, une jolie mise en forme a été appliquée à notre JSON, qui divise chaque propriété sur sa propre ligne en retrait avec un espace pour indiquer le niveau d'imbrication de chaque propriété.

Le portail comprend un explorateur de documents, alors utilisons-le maintenant pour récupérer le document que nous venons de créer.

Step 5- Choisissez une base de données et n'importe quelle collection dans la base de données pour afficher les documents de cette collection. Nous n'avons actuellement qu'une seule base de données nommée myfirstdb avec une collection appelée Families, qui ont toutes deux été présélectionnées ici dans les listes déroulantes.

Par défaut, l'Explorateur de documents affiche une liste non filtrée de documents dans la collection, mais vous pouvez également rechercher n'importe quel document spécifique par ID ou plusieurs documents en fonction d'une recherche générique d'un ID partiel.

Nous n'avons qu'un seul document dans notre collection à ce jour, et nous voyons son identifiant sur l'écran suivant, AndersonFamily.

Step 6 - Cliquez sur l'ID pour afficher le document.

Création de documents avec le SDK .NET

Comme vous savez que les documents ne sont qu'un autre type de ressource et que vous vous êtes déjà familiarisé avec le traitement des ressources à l'aide du SDK.

  • La seule grande différence entre les documents et les autres ressources est que, bien sûr, ils sont sans schéma.

  • Il existe donc de nombreuses options. Naturellement, vous pouvez simplement travailler des graphiques d'objets JSON ou même des chaînes brutes de texte JSON, mais vous pouvez également utiliser des objets dynamiques qui vous permettent de vous lier à des propriétés au moment de l'exécution sans définir de classe au moment de la compilation.

  • Vous pouvez également travailler avec de vrais objets C #, ou Entités comme ils sont appelés, qui peuvent être vos classes de domaine métier.

Commençons par créer des documents à l'aide du SDK .Net. Voici les étapes.

Step 1 - Instanciez DocumentClient puis nous interrogerons la base de données myfirstdb, puis nous interrogerons la collection MyCollection, que nous stockons dans cette collection de variables privées afin qu'elle soit accessible dans toute la classe.

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 - Créez des documents dans la tâche 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(); 
}

Le premier document sera généré à partir de cet objet dynamique. Cela peut ressembler à JSON, mais bien sûr ce n'est pas le cas. C'est du code C # et nous créons un véritable objet .NET, mais il n'y a pas de définition de classe. Au lieu de cela, les propriétés sont déduites de la façon dont l'objet est initialisé.

Notez que nous n'avons pas fourni de propriété Id pour ce document.

Jetons maintenant un œil à CreateDocument. Cela ressemble au même modèle que nous avons vu pour la création de bases de données et de collections.

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- Cette fois, nous appelons CreateDocumentAsync en spécifiant le SelfLink de la collection à laquelle nous voulons ajouter le document. Nous obtenons une réponse avec une propriété de ressource qui, dans ce cas, représente le nouveau document avec ses propriétés générées par le système.

L'objet Document est une classe définie dans le SDK qui hérite de la ressource et possède donc toutes les propriétés de ressource communes, mais il inclut également les propriétés dynamiques qui définissent le document sans schéma lui-même.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** 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

Comme vous pouvez le voir, nous n'avons pas fourni d'identifiant, mais DocumentDB a généré celui-ci pour nous pour le nouveau document.

Dans DocumentDB, nous utilisons en fait SQL pour interroger des documents, donc ce chapitre est consacré à l'interrogation à l'aide de la syntaxe SQL spéciale de DocumentDB. Bien que si vous faites du développement .NET, il existe également un fournisseur LINQ qui peut être utilisé et qui peut générer le SQL approprié à partir d'une requête LINQ.

Interroger un document à l'aide du portail

Le portail Azure dispose d'un explorateur de requêtes qui vous permet d'exécuter n'importe quelle requête SQL sur votre base de données DocumentDB.

Nous utiliserons l'explorateur de requêtes pour démontrer les nombreuses capacités et fonctionnalités du langage de requête en commençant par la requête la plus simple possible.

Step 1 - Dans le panneau Base de données, cliquez pour ouvrir le panneau Explorateur de requêtes.

N'oubliez pas que les requêtes s'exécutent dans le cadre d'une collection et que l'explorateur de requêtes vous permet de choisir la collection dans cette liste déroulante.

Step 2 - Sélectionnez la collection Familles créée précédemment à l'aide du portail.

L'Explorateur de requêtes s'ouvre avec cette simple requête SELECT * FROM c, qui récupère simplement tous les documents de la collection.

Step 3- Exécutez cette requête en cliquant sur le bouton «Exécuter la requête». Ensuite, vous verrez que le document complet est récupéré dans le panneau Résultats.

Interroger un document à l'aide du SDK .Net

Voici les étapes pour exécuter certaines requêtes de document à l'aide du SDK .Net.

Dans cet exemple, nous voulons interroger les documents nouvellement créés que nous venons d'ajouter.

Step 1 - Appelez CreateDocumentQuery, en passant la collection sur laquelle exécuter la requête par son SelfLink et le texte de la requête.

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

Cette requête renvoie également tous les documents de la collection entière, mais nous n'appelons pas .ToList sur CreateDocumentQuery comme auparavant, ce qui émettrait autant de requêtes que nécessaire pour extraire tous les résultats dans une seule ligne de code.

Step 2 - Au lieu de cela, appelez AsDocumentQuery et cette méthode retourne un objet de requête avec une propriété HasMoreResults.

Step 3 - Si HasMoreResults est vrai, alors appelez ExecuteNextAsync pour obtenir le morceau suivant, puis videz tout le contenu de ce morceau.

Step 4- Vous pouvez également interroger en utilisant LINQ au lieu de SQL si vous préférez. Ici, nous avons défini une requête LINQ dans q, mais elle ne s'exécutera pas tant que nous n'exécuterons pas .ToList dessus.

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

Le SDK convertira notre requête LINQ en syntaxe SQL pour DocumentDB, générant une clause SELECT et WHERE basée sur notre syntaxe LINQ

Step 5 - Appelez maintenant les requêtes ci-dessus à partir de la tâche 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); 
   } 
	
}

Lorsque le code ci-dessus est exécuté, vous recevrez la sortie suivante.

**** 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

Dans ce chapitre, nous allons apprendre comment mettre à jour les documents. À l'aide du portail Azure, vous pouvez facilement mettre à jour le document en ouvrant le document dans l'Explorateur de documents et en le mettant à jour dans l'éditeur comme un fichier texte.

Cliquez sur le bouton «Enregistrer». Désormais, lorsque vous devez modifier un document à l'aide du SDK .Net, vous pouvez simplement le remplacer. Vous n'avez pas besoin de le supprimer et de le recréer, ce qui en plus d'être fastidieux, modifierait également l'ID de la ressource, ce que vous ne voudriez pas faire lorsque vous ne faites que modifier un document. Voici les étapes suivantes pour mettre à jour le document à l'aide du SDK .Net.

Jetons un coup d'œil à la tâche ReplaceDocuments suivante où nous interrogerons les documents où la propriété isNew est vraie, mais nous n'en obtiendrons aucun car il n'y en a pas. Alors, modifions les documents que nous avons ajoutés précédemment, ceux dont les noms commencent par Nouveau client.

Step 1 - Ajoutez la propriété isNew à ces documents et définissez sa valeur sur 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 - Obtenez les documents à mettre à jour en utilisant la même requête STARTSWITH et cela nous donne les documents, que nous récupérons ici sous forme d'objets dynamiques.

Step 3 - Attachez la propriété isNew et définissez-la sur true pour chaque document.

Step 4 - Appelez ReplaceDocumentAsync, en passant le SelfLink du document, avec le document mis à jour.

Maintenant, juste pour prouver que cela a fonctionné, recherchez les documents où isNew est égal à vrai. Appelons les requêtes ci-dessus à partir de la tâche 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); 
   }
	
}

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** 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

Dans ce chapitre, nous allons apprendre comment supprimer un document de votre compte DocumentDB. À l'aide d'Azure Portal, vous pouvez facilement supprimer n'importe quel document en ouvrant le document dans l'Explorateur de documents et en cliquant sur l'option «Supprimer».

Il affichera le message de confirmation. Appuyez maintenant sur le bouton Oui et vous verrez que le document n'est plus disponible dans votre compte DocumentDB.

Maintenant, lorsque vous souhaitez supprimer un document à l'aide du SDK .Net.

Step 1- C'est le même modèle que nous avons vu précédemment où nous allons d'abord demander les SelfLinks de chaque nouveau document. Nous n'utilisons pas SELECT * ici, qui retournerait les documents dans leur intégralité, dont nous n'avons pas besoin.

Step 2 - Au lieu de cela, nous sélectionnons simplement les SelfLinks dans une liste, puis nous appelons simplement DeleteDocumentAsync pour chaque SelfLink, un à la fois, pour supprimer les documents de la collection.

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 - Appelons maintenant les DeleteDocuments ci-dessus à partir de la tâche 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 DeleteDocuments(client); 
   } 
}

Lorsque le code ci-dessus est exécuté, vous recevrez la sortie suivante.

***** Delete Documents *****  
Quering for documents to be deleted 
Found 2 documents to be deleted 
Deleted 2 new customer documents

Bien que les bases de données sans schéma, telles que DocumentDB, facilitent la prise en compte des modifications de votre modèle de données, vous devriez quand même passer un peu de temps à réfléchir à vos données.

  • Tu as beaucoup d'options. Naturellement, vous pouvez simplement travailler des graphiques d'objets JSON ou même des chaînes brutes de texte JSON, mais vous pouvez également utiliser des objets dynamiques qui vous permettent de vous lier à des propriétés au moment de l'exécution sans définir de classe au moment de la compilation.

  • Vous pouvez également travailler avec de vrais objets C #, ou Entités comme ils sont appelés, qui peuvent être vos classes de domaine métier.

Des relations

Jetons un coup d'œil à la structure hiérarchique du document. Il a quelques propriétés de premier niveau comme l'id requis, ainsi que lastName et isRegistered, mais il a également des propriétés imbriquées.

{ 
   "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 
}
  • Par exemple, la propriété parents est fournie sous forme de tableau JSON comme indiqué par les crochets.

  • Nous avons également un autre tableau pour les enfants, même s'il n'y a qu'un seul enfant dans le tableau dans cet exemple. C'est ainsi que vous modélisez l'équivalent des relations un-à-plusieurs dans un document.

  • Vous utilisez simplement des tableaux où chaque élément du tableau peut être une valeur simple ou un autre objet complexe, voire un autre tableau.

  • Ainsi, une famille peut avoir plusieurs parents et plusieurs enfants et si vous regardez les objets enfants, ils ont la propriété d'un animal qui est lui-même un tableau imbriqué pour une relation un à plusieurs entre les enfants et les animaux domestiques.

  • Pour la propriété location, nous combinons trois propriétés associées, l'état, le comté et la ville dans un objet.

  • Incorporer un objet de cette façon plutôt que d'incorporer un tableau d'objets est similaire à avoir une relation un-à-un entre deux lignes dans des tables séparées dans une base de données relationnelle.

Incorporer des données

Lorsque vous commencez à modéliser des données dans un magasin de documents, tel que DocumentDB, essayez de traiter vos entités comme des documents autonomes représentés dans JSON. Lorsque nous travaillons avec des bases de données relationnelles, nous normalisons toujours les données.

  • Normaliser vos données implique généralement de prendre une entité, telle qu'un client, et de la décomposer en éléments de données discrets, comme les coordonnées et les adresses.

  • Pour lire un client, avec toutes ses coordonnées et adresses, vous devez utiliser JOINS pour agréger efficacement vos données au moment de l'exécution.

Voyons maintenant comment nous modéliserons les mêmes données qu'une entité autonome dans une base de données de documents.

{
   "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} 
   ]
}

Comme vous pouvez le constater, nous avons dénormalisé l'enregistrement client où toutes les informations du client sont intégrées dans un seul document JSON.

Dans NoSQL, nous avons un schéma gratuit, vous pouvez donc également ajouter des coordonnées et des adresses dans un format différent. Dans NoSQL, vous pouvez récupérer un enregistrement client de la base de données en une seule opération de lecture. De même, la mise à jour d'un enregistrement est également une opération d'écriture unique.

Voici les étapes de création de documents à l'aide du SDK .Net.

Step 1- Instanciez DocumentClient. Ensuite, nous interrogerons la base de données myfirstdb et également la collection MyCollection, que nous stockons dans cette collection de variables privées afin qu'elle soit accessible dans toute la classe.

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 - Créez des documents dans la tâche 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(); 
}

Le premier document sera généré à partir de cet objet dynamique. Cela peut ressembler à JSON, mais bien sûr ce n'est pas le cas. C'est du code C # et nous créons un véritable objet .NET, mais il n'y a pas de définition de classe. Au lieu de cela, les propriétés sont déduites de la façon dont l'objet est initialisé. Vous pouvez également remarquer que nous n'avons pas fourni de propriété Id pour ce document.

Step 3 - Jetons maintenant un coup d'œil au CreateDocument et il ressemble au même modèle que nous avons vu pour la création de bases de données et de collections.

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- Cette fois, nous appelons CreateDocumentAsync en spécifiant le SelfLink de la collection à laquelle nous voulons ajouter le document. Nous obtenons une réponse avec une propriété de ressource qui, dans ce cas, représente le nouveau document avec ses propriétés générées par le système.

Dans la tâche CreateDocuments suivante, nous avons créé trois documents.

  • Dans le premier document, l'objet Document est une classe définie dans le SDK qui hérite de la ressource et possède donc toutes les propriétés de ressource communes, mais il inclut également les propriétés dynamiques qui définissent le document sans schéma lui-même.

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(); 
}
  • Ce deuxième document fonctionne uniquement avec une chaîne JSON brute. Nous entrons maintenant dans une surcharge pour CreateDocument qui utilise JavaScriptSerializer pour dé-sérialiser la chaîne en un objet, qu'il transmet ensuite à la même méthode CreateDocument que nous avons utilisée pour créer le premier document.

  • Dans le troisième document, nous avons utilisé l'objet C # Customer qui est défini dans notre application.

Jetons un coup d'œil à ce client, il a une propriété Id et adresse où l'adresse est un objet imbriqué avec ses propres propriétés, y compris l'emplacement, qui est encore un autre objet imbriqué.

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

Nous avons également des attributs de propriété JSON en place, car nous souhaitons maintenir les conventions appropriées des deux côtés de la clôture.

Je crée donc simplement mon objet Nouveau client avec ses objets enfants imbriqués et j'appelle à nouveau CreateDocument. Bien que notre objet client ait une propriété Id, nous n'avons pas fourni de valeur pour lui et DocumentDB en a donc généré une basée sur le GUID, tout comme il l'a fait pour les deux documents précédents.

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** 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 ou JavaScript Object Notation est un standard ouvert basé sur du texte léger conçu pour l'échange de données lisible par l'homme et également facile à analyser et à générer pour les machines. JSON est au cœur de DocumentDB. Nous transmettons JSON sur le fil, nous stockons JSON en tant que JSON et nous indexons l'arborescence JSON permettant les requêtes sur le document JSON complet.

Le format JSON prend en charge les types de données suivants -

S.No. Type et description
1

Number

Format à virgule flottante double précision en JavaScript

2

String

Unicode entre guillemets doubles avec échappement de barre oblique inverse

3

Boolean

Vrai ou faux

4

Array

Une séquence ordonnée de valeurs

5

Value

Cela peut être une chaîne, un nombre, vrai ou faux, nul, etc.

6

Object

Une collection non ordonnée de paires clé: valeur

sept

Whitespace

Il peut être utilisé entre n'importe quelle paire de jetons

8

Null

Vide

Jetons un coup d'œil à un exemple simple de type DateTime. Ajoutez la date de naissance à la classe client.

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

Nous pouvons stocker, récupérer et interroger à l'aide de DateTime comme indiqué dans le code suivant.

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

Lorsque le code ci-dessus est compilé et exécuté et que le document est créé, vous verrez que la date de naissance est ajoutée maintenant.

**** 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 a récemment ajouté un certain nombre d'améliorations sur la façon dont vous pouvez interroger Azure DocumentDB, telles que le mot clé TOP vers la grammaire SQL, qui a accéléré l'exécution des requêtes et consommé moins de ressources, augmenté les limites des opérateurs de requête et ajouté la prise en charge d'opérateurs LINQ supplémentaires dans le SDK .NET.

Jetons un coup d'œil à un exemple simple dans lequel nous ne récupérerons que les deux premiers enregistrements. Si vous disposez d'un certain nombre d'enregistrements et que vous souhaitez n'en récupérer que certains, vous pouvez utiliser le mot-clé Top. Dans cet exemple, nous avons de nombreux enregistrements de tremblements de terre.

Maintenant, nous voulons afficher les deux premiers enregistrements uniquement

Step 1 - Accédez à l'explorateur de requêtes et exécutez cette requête.

SELECT * FROM c 
WHERE c.magnitude > 2.5

Vous verrez qu'il a récupéré quatre enregistrements car nous n'avons pas encore spécifié le mot clé TOP.

Step 2- Utilisez maintenant le mot clé TOP avec la même requête. Ici, nous avons spécifié le mot clé TOP et «2» signifie que nous ne voulons que deux enregistrements.

SELECT TOP 2 * FROM c 
WHERE c.magnitude > 2.5

Step 3 - Exécutez maintenant cette requête et vous verrez que seuls deux enregistrements sont récupérés.

De même, vous pouvez utiliser le mot clé TOP dans le code à l'aide du SDK .Net. Voici la mise en œuvre.

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

Voici la tâche CreateDocumentClient dans laquelle sont instanciés la base de données DocumentClient et tremblement de terre.

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

Lorsque le code ci-dessus est compilé et exécuté, vous verrez que seuls trois enregistrements sont récupérés.

**** 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 prend en charge l'interrogation de documents à l'aide de SQL sur des documents JSON. Vous pouvez trier les documents de la collection sur des nombres et des chaînes à l'aide d'une clause ORDER BY dans votre requête. La clause peut inclure un argument ASC / DESC facultatif pour spécifier l'ordre dans lequel les résultats doivent être récupérés.

Jetons un œil à l'exemple suivant dans lequel nous avons un document 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
      }
   ]
	
}

Voici la requête SQL pour trier le résultat dans un ordre décroissant.

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

Lorsque la requête ci-dessus est exécutée, vous recevrez la sortie suivante.

[
   {
      "description": "Grapes, red or green (European type, such as Thompson
         seedless), raw",
      "foodGroup": "Fruits and Fruit Juices",
      "servingDescription": "NLEA serving",
      "servingWeight": 126
   }
]

Par défaut, DocumentDB indexe automatiquement toutes les propriétés d'un document dès que le document est ajouté à la base de données. Cependant, vous pouvez prendre le contrôle et affiner votre propre politique d'indexation qui réduit la surcharge de stockage et de traitement lorsqu'il existe des documents et / ou des propriétés spécifiques qui n'ont jamais besoin d'être indexés.

La stratégie d'indexation par défaut qui indique à DocumentDB d'indexer automatiquement chaque propriété convient à de nombreux scénarios courants. Mais vous pouvez également implémenter une stratégie personnalisée qui exerce un contrôle précis sur exactement ce qui est indexé et ce qui ne l'est pas et d'autres fonctionnalités en ce qui concerne l'indexation.

DocumentDB prend en charge les types d'indexation suivants -

  • Hash
  • Range

Hacher

L'index de hachage permet une interrogation efficace pour l'égalité, c'est-à-dire lors de la recherche de documents où une propriété donnée est égale à une valeur exacte, plutôt que de correspondre sur une plage de valeurs comme inférieure à, supérieure à ou entre.

Vous pouvez effectuer des requêtes de plage avec un index de hachage, mais DocumentDB ne pourra pas utiliser l'index de hachage pour trouver les documents correspondants et devra à la place analyser séquentiellement chaque document pour déterminer s'il doit être sélectionné par la requête de plage.

Vous ne pourrez pas trier vos documents avec une clause ORDER BY sur une propriété qui n'a qu'un index de hachage.

Intervalle

Index de plage défini pour la propriété, DocumentDB permet d'interroger efficacement des documents par rapport à une plage de valeurs. Il vous permet également de trier les résultats de la requête sur cette propriété, en utilisant ORDER BY.

DocumentDB vous permet de définir à la fois un hachage et un index de plage sur une ou toutes les propriétés, ce qui permet des requêtes d'égalité et de plage efficaces, ainsi que ORDER BY.

Politique d'indexation

Chaque collection a une politique d'indexation qui dicte quels types d'index sont utilisés pour les nombres et les chaînes dans chaque propriété de chaque document.

  • Vous pouvez également contrôler si les documents sont indexés automatiquement lorsqu'ils sont ajoutés à la collection.

  • L'indexation automatique est activée par défaut, mais vous pouvez remplacer ce comportement lors de l'ajout d'un document, en indiquant à DocumentDB de ne pas indexer ce document particulier.

  • Vous pouvez désactiver l'indexation automatique afin que, par défaut, les documents ne soient pas indexés lorsqu'ils sont ajoutés à la collection. De même, vous pouvez remplacer cela au niveau du document et demander à DocumentDB d'indexer un document particulier lors de son ajout à la collection. C'est ce qu'on appelle l'indexation manuelle.

Inclure / exclure l'indexation

Une politique d'indexation peut également définir le ou les chemins à inclure ou à exclure de l'index. Ceci est utile si vous savez qu'il existe certaines parties d'un document sur lesquelles vous n'interrogez jamais et certaines parties que vous faites.

Dans ces cas, vous pouvez réduire la surcharge d'indexation en demandant à DocumentDB d'indexer uniquement les parties particulières de chaque document ajouté à la collection.

Indexation automatique

Jetons un coup d'œil à un exemple simple d'indexation automatique.

Step 1 - Tout d'abord, nous créons une collection appelée auto-indexation et sans fournir explicitement de politique, cette collection utilise la politique d'indexation par défaut, ce qui signifie que l'indexation automatique est activée sur cette collection.

Ici, nous utilisons le routage basé sur l'ID pour la liaison automatique de la base de données, nous n'avons donc pas besoin de connaître son ID de ressource ou de l'interroger avant de créer la collection. Nous pouvons simplement utiliser l'ID de la base de données, qui est mydb.

Step 2 - Créons maintenant deux documents, tous deux portant le nom d'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");
}

Ce premier, pour Mark Upston, est ajouté à la collection et est ensuite immédiatement indexé automatiquement en fonction de la politique d'indexation par défaut.

Mais lorsque le deuxième document pour Mark Upston est ajouté, nous avons passé les options de requête avec IndexingDirective.Exclude qui indique explicitement à DocumentDB de ne pas indexer ce document, malgré la politique d'indexation de la collection.

Nous avons différents types de requêtes pour les deux documents à la fin.

Step 3 - Appelons la tâche AutomaticIndexing de CreateDocumentClient.

private static async Task CreateDocumentClient() {
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { 
      await AutomaticIndexing(client); 
   } 
}

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** Override Automatic Indexing **** 
Documents WHERE lastName = 'Upston': 1 
All documents: 2 
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oAOEkfQA=/docs/kV5oAOEkfQACA 
AAAAAAAAA==/

Comme vous pouvez le voir, nous avons deux de ces documents, mais la requête ne renvoie que celui de Mark car celui de Mark n'est pas indexé. Si nous interrogeons à nouveau, sans clause WHERE pour récupérer tous les documents de la collection, alors nous obtenons un jeu de résultats avec les deux documents et c'est parce que les documents non indexés sont toujours retournés par des requêtes qui n'ont pas de clause WHERE.

Nous pouvons également récupérer des documents non indexés par leur identifiant ou leur auto-lien. Ainsi, lorsque nous interrogeons le document de Mark par son ID, MARK, nous voyons que DocumentDB renvoie le document même s'il n'est pas indexé dans la collection.

Indexation manuelle

Jetons un coup d'œil à un exemple simple d'indexation manuelle en remplaçant l'indexation automatique.

Step 1- Nous allons d'abord créer une collection appelée indexation manuelle et remplacer la politique par défaut en désactivant explicitement l'indexation automatique. Cela signifie que, sauf demande contraire de notre part, les nouveaux documents ajoutés à cette collection ne seront pas indexés.

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- Nous allons maintenant créer à nouveau les deux mêmes documents qu'auparavant. Nous ne fournirons aucune option de demande spéciale pour le document de Mark cette fois, en raison de la politique d'indexation de la collection, ce document ne sera pas indexé.

Step 3 - Maintenant, lorsque nous ajoutons le deuxième document pour Mark, nous utilisons RequestOptions avec IndexingDirective.Include pour indiquer à DocumentDB qu'il doit indexer ce document, ce qui remplace la politique d'indexation de la collection qui dit qu'il ne devrait pas.

Nous avons différents types de requêtes pour les deux documents à la fin.

Step 4 - Appelons la tâche ManualIndexing depuis CreateDocumentClient.

private static async Task CreateDocumentClient() {
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
      await ManualIndexing(client); 
   } 
}

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** Manual Indexing **** 
Documents WHERE lastName = 'Upston': 1 
All documents: 2 
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oANHJPgE=/docs/kV5oANHJPgEBA 
AAAAAAAAA==/

Encore une fois, la requête ne renvoie qu'un seul des deux documents, mais cette fois, elle renvoie Jane Doe, dont nous avons explicitement demandé l'indexation. Mais encore une fois, une requête sans clause WHERE récupère tous les documents de la collection, y compris le document non indexé pour Mark. Nous pouvons également rechercher le document non indexé par son ID, que DocumentDB renvoie même s'il n'est pas indexé.

Microsoft a ajouté geospatial support, qui vous permet de stocker des données de localisation dans vos documents et d'effectuer des calculs spatiaux pour la distance et les intersections entre les points et les polygones.

  • Les données spatiales décrivent la position et la forme des objets dans l'espace.

  • En règle générale, il peut être utilisé pour représenter l'emplacement d'une personne, un lieu d'intérêt ou les limites d'une ville ou d'un lac.

  • Les cas d'utilisation courants impliquent souvent des requêtes de proximité. Par exemple, "trouver toutes les universités à proximité de mon emplacement actuel".

UNE Pointdésigne une seule position dans l'espace qui représente l'emplacement exact, par exemple l'adresse postale d'une université particulière. Un point est représenté dans DocumentDB à l'aide de sa paire de coordonnées (longitude et latitude). Voici un exemple de point JSON.

{ 
   "type":"Point", 
   "coordinates":[ 28.3, -10.7 ] 
}

Jetons un coup d'œil à un exemple simple qui contient l'emplacement d'une université.

{ 
   "id":"case-university", 
   "name":"CASE: Center For Advanced Studies In Engineering", 
   "city":"Islamabad", 
	
   "location": { 
      "type":"Point", 
      "coordinates":[ 33.7194136, -73.0964862 ] 
   } 
}

Pour récupérer le nom de l'université en fonction de l'emplacement, vous pouvez utiliser la requête suivante.

SELECT c.name FROM c 

WHERE c.id = "case-university" AND ST_ISVALID({ 
      "type":"Point", 
      "coordinates":[ 33.7194136, -73.0964862 ]})

Lorsque la requête ci-dessus est exécutée, vous recevrez la sortie suivante.

[ 
   { 
      "name": "CASE: Center For Advanced Studies In Engineering" 
   } 
]

Créer un document avec des données géospatiales dans .NET

Vous pouvez créer un document avec des données géospatiales, jetons un coup d'œil à un exemple simple dans lequel un document universitaire est créé.

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

Voici l'implémentation de la classe 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; } 
}

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** 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

Lorsque votre base de données commence à croître au-delà de 10 Go, vous pouvez évoluer simplement en créant de nouvelles collections, puis en répartissant ou en partitionnant vos données sur de plus en plus de collections.

Tôt ou tard, une seule collection, d'une capacité de 10 Go, ne suffira pas à contenir votre base de données. Maintenant, 10 Go peut ne pas sembler un très grand nombre, mais rappelez-vous que nous stockons des documents JSON, qui ne sont que du texte brut et que vous pouvez contenir de nombreux documents en texte brut dans 10 Go, même si vous prenez en compte la surcharge de stockage des index.

Le stockage n'est pas le seul problème en matière d'évolutivité. Le débit maximal disponible sur une collection est de deux mille cinq cent unités de demande par seconde que vous obtenez avec une collection S3. Par conséquent, si vous avez besoin d'un débit plus élevé, vous devrez également évoluer en partitionnant avec plusieurs collections. Le partitionnement avec montée en puissance est également appeléhorizontal partitioning.

Il existe de nombreuses approches qui peuvent être utilisées pour partitionner les données avec Azure DocumentDB. Voici les stratégies les plus courantes -

  • Partitionnement Spillover
  • Partitionnement de plage
  • Recherche de partitionnement
  • Partitionnement de hachage

Partitionnement Spillover

Le partitionnement par débordement est la stratégie la plus simple car il n'y a pas de clé de partition. C'est souvent un bon choix pour commencer lorsque vous n'êtes pas sûr de beaucoup de choses. Vous ne savez peut-être pas si vous aurez même besoin d'évoluer au-delà d'une seule collection, combien de collections vous devrez peut-être ajouter ou à quelle vitesse vous devrez peut-être les ajouter.

  • Le partitionnement de débordement commence par une seule collection et il n'y a pas de clé de partition.

  • La collection commence à se développer, puis se développe un peu plus, puis encore plus, jusqu'à ce que vous commenciez à vous rapprocher de la limite de 10 Go.

  • Lorsque vous atteignez une capacité de 90%, vous accédez à une nouvelle collection et commencez à l'utiliser pour de nouveaux documents.

  • Une fois que votre base de données évolue vers un plus grand nombre de collections, vous voudrez probablement passer à une stratégie basée sur une clé de partition.

  • Lorsque vous faites cela, vous devrez rééquilibrer vos données en déplaçant les documents vers différentes collections en fonction de la stratégie vers laquelle vous migrez.

Partitionnement de plage

L'une des stratégies les plus courantes est le partitionnement par plage. Avec cette approche, vous déterminez la plage de valeurs dans laquelle la clé de partition d'un document peut appartenir et dirigez le document vers une collection correspondant à cette plage.

  • Les dates sont très généralement utilisées avec cette stratégie où vous créez une collection pour contenir des documents compris dans la plage de dates définie. Lorsque vous définissez des plages suffisamment petites, vous êtes sûr qu'aucune collection ne dépassera jamais sa limite de 10 Go. Par exemple, il peut y avoir un scénario où une seule collection peut raisonnablement traiter des documents pendant un mois entier.

  • Il se peut également que la plupart des utilisateurs demandent des données actuelles, qui seraient des données pour ce mois ou peut-être le mois dernier, mais les utilisateurs recherchent rarement des données beaucoup plus anciennes. Vous commencez donc en juin avec une collection S3, qui est la collection la plus chère que vous puissiez acheter et qui offre le meilleur débit possible.

  • En juillet, vous achetez une autre collection S3 pour stocker les données de juillet et vous réduisez également les données de juin à une collection S2 moins chère. Puis en août, vous obtenez une autre collection S3 et réduisez juillet à un S2 et juin à un S1. Cela va, mois après mois, où vous gardez toujours les données actuelles disponibles pour un débit élevé et où les données plus anciennes sont maintenues disponibles à des débits inférieurs.

  • Tant que la requête fournit une clé de partition, seule la collection qui doit être interrogée sera interrogée et pas toutes les collections de la base de données comme cela se produit avec le partitionnement de débordement.

Recherche de partitionnement

Avec le partitionnement de recherche, vous pouvez définir une carte de partition qui achemine les documents vers des collections spécifiques en fonction de leur clé de partition. Par exemple, vous pouvez partitionner par région.

  • Stockez tous les documents américains dans une seule collection, tous les documents européens dans une autre collection et tous les documents de toute autre région dans une troisième collection.

  • Utilisez cette carte de partition et un résolveur de partition de recherche peut déterminer dans quelle collection créer un document et quelles collections interroger, en fonction de la clé de partition, qui est la propriété de région contenue dans chaque document.

Partitionnement de hachage

Dans le partitionnement de hachage, les partitions sont attribuées en fonction de la valeur d'une fonction de hachage, ce qui vous permet de répartir uniformément les demandes et les données sur un certain nombre de partitions.

Ceci est couramment utilisé pour partitionner les données produites ou consommées à partir d'un grand nombre de clients distincts, et est utile pour stocker des profils utilisateur, des éléments de catalogue, etc.

Jetons un coup d'œil à un exemple simple de partitionnement de plage à l'aide du RangePartitionResolver fourni par le SDK .NET.

Step 1- Créez un nouveau DocumentClient et nous créerons deux collections dans la tâche CreateCollections. L'un contiendra des documents pour les utilisateurs qui ont des ID utilisateur commençant par A à M et l'autre pour les ID utilisateur 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 - Enregistrez le résolveur de plage pour la base de données.

Step 3- Créez un nouveau RangePartitionResolver <string>, qui est le type de données de notre clé de partition. Le constructeur prend deux paramètres, le nom de propriété de la clé de partition et un dictionnaire qui est la carte de partition ou la carte de partition, qui est juste une liste des plages et des collections correspondantes que nous prédéfinissons pour le résolveur.

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

Il est nécessaire d'encoder ici la plus grande valeur UTF-8 possible. Ou bien la première plage ne correspondrait à aucun Ms sauf le seul M, et de même pour Z dans la deuxième plage. Donc, vous pouvez simplement considérer cette valeur codée ici comme un caractère générique pour la correspondance sur la clé de partition.

Step 4- Après avoir créé le résolveur, enregistrez-le pour la base de données avec le DocumentClient actuel. Pour ce faire, affectez-le simplement à la propriété de dictionnaire du PartitionResolver.

Nous créerons et interrogerons des documents par rapport à la base de données, et non une collection comme vous le faites normalement, le résolveur utilisera cette carte pour acheminer les demandes vers les collections appropriées.

Créons maintenant quelques documents. Nous allons d'abord en créer un pour userId Kirk, puis un pour 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); 
}

Le premier paramètre ici est un auto-lien vers la base de données, pas une collection spécifique. Ce n'est pas possible sans un résolveur de partition, mais avec un seul, cela fonctionne de manière transparente.

Les deux documents ont été enregistrés dans la base de données myfirstdb, mais nous savons que Kirk est stocké dans la collection pour A à M et Spock est stocké dans la collection pour N à Z, si notre RangePartitionResolver fonctionne correctement.

Appelons-les à partir de la tâche CreateDocumentClient comme indiqué dans le code suivant.

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

Lorsque le code ci-dessus est exécuté, vous recevrez la sortie suivante.

**** Create Documents Across Partitions **** 
Document 1: dbs/Ic8LAA==/colls/Ic8LAO2DxAA=/docs/Ic8LAO2DxAABAAAAAAAAAA==/ 
Document 2: dbs/Ic8LAA==/colls/Ic8LAP12QAE=/docs/Ic8LAP12QAEBAAAAAAAAAA==/

Comme on l'a vu, les auto-liens des deux documents ont des ID de ressources différents car ils existent dans deux collections distinctes.

Avec l'outil de migration de données DocumentDB, vous pouvez facilement migrer les données vers DocumentDB. L'outil de migration de données DocumentDB est un utilitaire gratuit et open source que vous pouvez télécharger à partir du Centre de téléchargement Microsofthttps://www.microsoft.com/

L'outil de migration prend en charge de nombreuses sources de données, dont certaines sont répertoriées ci-dessous -

  • serveur SQL
  • Fichiers JSON
  • Fichiers plats de valeurs séparées par des virgules (CSV)
  • MongoDB
  • Stockage de table Azure
  • Amazon DynamoDB
  • HBase et même d'autres bases de données DocumentDB

Après avoir téléchargé l'outil de migration de données DocumentDB, extrayez le fichier zip.

Vous pouvez voir deux exécutables dans ce dossier, comme illustré dans la capture d'écran suivante.

Tout d'abord, il y a dt.exe, qui est la version console avec une interface de ligne de commande, puis il y a dtui.exe, qui est la version de bureau avec une interface utilisateur graphique.

Lançons la version GUI.

Vous pouvez voir la page d'accueil. Cliquez sur «Suivant» pour la page Informations sur la source.

Voici où vous configurez votre source de données, et vous pouvez voir les nombreux choix pris en charge dans le menu déroulant.

Lorsque vous effectuez une sélection, le reste de la page Informations sur la source change en conséquence.

Il est très facile d'importer des données dans DocumentDB à l'aide de l'outil de migration de données DocumentDB. Nous vous recommandons d'exercer les exemples ci-dessus et d'utiliser également les autres fichiers de données.

DocumentDB fournit les concepts pour contrôler l'accès aux ressources DocumentDB. L'accès aux ressources DocumentDB est régi par un jeton de clé principale ou un jeton de ressource. Les connexions basées sur des jetons de ressources peuvent uniquement accéder aux ressources spécifiées par les jetons et aucune autre ressource. Les jetons de ressources sont basés sur les autorisations des utilisateurs.

  • Vous créez d'abord un ou plusieurs utilisateurs, et ceux-ci sont définis au niveau de la base de données.

  • Ensuite, vous créez une ou plusieurs autorisations pour chaque utilisateur, en fonction des ressources auxquelles vous souhaitez autoriser chaque utilisateur à accéder.

  • Chaque autorisation génère un jeton de ressource qui permet un accès en lecture seule ou complet à une ressource donnée et qui peut être n'importe quelle ressource utilisateur dans la base de données.

  • Les utilisateurs sont définis au niveau de la base de données et les autorisations sont définies pour chaque utilisateur.

  • Les utilisateurs et les autorisations s'appliquent à toutes les collections de la base de données.

Jetons un coup d'œil à un exemple simple dans lequel nous allons apprendre à définir les utilisateurs et les autorisations pour obtenir une sécurité granulaire dans DocumentDB.

Nous allons commencer avec un nouveau DocumentClient et interroger la base de données 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");
   }
}

Voici l'implémentation de 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- Créez deux utilisateurs, Alice et Tom comme toute ressource que nous créons, nous construisons un objet de définition avec l'ID souhaité et appelons la méthode create et dans ce cas, nous appelons CreateUserAsync avec SelfLink de la base de données et userDefinition. Nous récupérons le résultat de la propriété de ressource dont nous obtenons l'objet utilisateur nouvellement créé.

Maintenant, pour voir ces deux nouveaux utilisateurs dans la base de données.

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- Appelez CreateUserQuery, par rapport à UsersLink de la base de données pour récupérer une liste de tous les utilisateurs. Ensuite, parcourez-les et affichez leurs propriétés.

Maintenant, nous devons d'abord les créer. Supposons donc que nous voulions autoriser Alice en lecture / écriture à la collection MyCollection, mais que Tom ne peut lire que les documents de la collection.

await CreatePermission(client, alice, "Alice Collection Access", PermissionMode.All,
   collection);
	
await CreatePermission(client, tom, "Tom Collection Access", PermissionMode.Read,
   collection);

Step 3- Créez une autorisation sur une ressource qui est la collection MyCollection, nous devons donc obtenir cette ressource un SelfLink.

Step 4 - Créez ensuite une Permission.Tout sur cette collection pour Alice et une Permission.Lisez sur cette collection pour Tom.

Voici l'implémentation de 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);
}

Comme vous devriez vous y attendre maintenant, nous le faisons en créant un objet de définition pour la nouvelle autorisation, qui comprend un Id et un permissionMode, qui est Permission.All ou Permission.Read, et le SelfLink de la ressource qui est sécurisée par la permission.

Step 5 - Appelez CreatePermissionAsync et obtenez l'autorisation créée à partir de la propriété de ressource dans le résultat.

Pour afficher l'autorisation créée, voici l'implémentation de 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); 
}

Cette fois, il s'agit d'une requête d'autorisation par rapport au lien des autorisations de l'utilisateur et nous listons simplement chaque autorisation retournée pour l'utilisateur.

Supprimons les autorisations d'Alice et de Tom.

await DeletePermission(client, alice, "Alice Collection Access"); 
await DeletePermission(client, tom, "Tom Collection Access");

Voici l'implémentation de 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 - Pour supprimer des autorisations, interrogez par ID d'autorisation pour obtenir le SelfLink, puis utilisez SelfLink pour supprimer l'autorisation.

Ensuite, supprimons les utilisateurs eux-mêmes. Supprimons les deux utilisateurs.

await DeleteUser(client, "Alice"); 
await DeleteUser(client, "Tom");

Voici l'implémentation de 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 - Première requête pour obtenir son SelfLink, puis appelez DeleteUserAsync pour supprimer son objet utilisateur.

Voici l'implémentation de la tâche CreateDocumentClient dans laquelle nous appelons toutes les tâches ci-dessus.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

**** 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

Dans ce chapitre, nous allons apprendre à visualiser les données stockées dans DocumentDB. Microsoft a fourni l'outil Power BI Desktop qui transforme vos données en visuels riches. Il vous permet également de récupérer des données à partir de diverses sources de données, de fusionner et de transformer les données, de créer des rapports et des visualisations puissants et de publier les rapports sur Power BI.

Dans la dernière version de Power BI Desktop, Microsoft a également ajouté la prise en charge de DocumentDB dans laquelle vous pouvez désormais vous connecter à votre compte DocumentDB. Vous pouvez télécharger cet outil à partir du lien,https://powerbi.microsoft.com

Jetons un coup d'œil à un exemple dans lequel nous allons visualiser les données sismiques importées dans le dernier chapitre.

Step 1 - Une fois l'outil téléchargé, lancez le bureau Power BI.

Step 2 - Cliquez sur l'option 'Obtenir les données' qui se trouve sur l'onglet Accueil sous le groupe Données externes et il affichera la page Obtenir les données.

Step 3 - Sélectionnez l'option Microsoft Azure DocumentDB (Beta) et cliquez sur le bouton «Connecter».

Step 4 - Entrez l'URL de votre compte Azure DocumentDB, de la base de données et de la collection à partir desquelles vous souhaitez visualiser les données et appuyez sur OK.

Si vous vous connectez à ce point de terminaison pour la première fois, vous serez invité à entrer la clé de compte.

Step 5 - Entrez la clé de compte (clé primaire) qui est unique pour chaque compte DocumentDB disponible sur le portail Azure, puis cliquez sur Se connecter.

Lorsque le compte est connecté avec succès, il récupère les données de la base de données spécifiée. Le volet Aperçu affiche une liste d'éléments d'enregistrement, un document est représenté sous la forme d'un type d'enregistrement dans Power BI.

Step 6 - Cliquez sur le bouton «Modifier» qui lancera l'éditeur de requête.

Step 7 - Dans l'éditeur de requêtes Power BI, vous devriez voir une colonne Document dans le volet central, cliquez sur le développement à droite de l'en-tête de colonne Document et sélectionnez les colonnes que vous souhaitez afficher.

Comme vous pouvez le voir, nous avons la latitude et la longitude comme colonnes séparées, mais nous visualisons les données sous forme de latitude et de coordonnées de longitude.

Step 8 - Pour ce faire, cliquez sur l'onglet «Ajouter une colonne».

Step 9 - Sélectionnez Ajouter une colonne personnalisée qui affichera la page suivante.

Step 10- Spécifiez le nouveau nom de colonne, disons LatLong et aussi la formule qui combinera la latitude et la longitude dans une colonne séparée par une virgule. Voici la formule.

Text.From([latitude])&", "&Text.From([longitude])

Step 11 - Cliquez sur OK pour continuer et vous verrez que la nouvelle colonne est ajoutée.

Step 12 - Allez dans l'onglet Accueil et cliquez sur l'option «Fermer et appliquer».

Step 13- Vous pouvez créer des rapports en faisant glisser et en déposant des champs dans le canevas de rapport. Vous pouvez voir sur la droite, il y a deux volets - un volet Visualisations et l'autre est le volet Champs.

Créons une vue cartographique montrant l'emplacement de chaque tremblement de terre.

Step 14 - Faites glisser le type visuel de carte depuis le volet Visualisations.

Step 15- Maintenant, faites glisser et déposez le champ LatLong du volet Champs vers la propriété Location dans le volet Visualisations. Ensuite, faites glisser et déposez le champ magnitude vers la propriété Values.

Step 16 - Faites glisser et déposez le champ de profondeur vers la propriété Saturation des couleurs.

Vous verrez maintenant le visuel de la carte montrant un ensemble de bulles indiquant l'emplacement de chaque tremblement de terre.