Allegati di Azure Cosmos DB

SI APPLICA A: Nosql Mongodb

Gli allegati di Azure Cosmos DB sono elementi speciali che contengono riferimenti a un metadati associato a un BLOB esterno o a un file multimediale.

Azure Cosmos DB supporta due tipi di allegati:

  • Gli allegati non gestiti sono un wrapper intorno a un riferimento URI a un BLOB archiviato in un servizio esterno, ad esempio Archiviazione di Azure, OneDrive e così via. Questo approccio è simile all'archiviazione di una proprietà URI in un elemento di Azure Cosmos DB standard.
  • Gli allegati gestiti sono BLOB gestiti e archiviati internamente da Azure Cosmos DB ed esposti tramite un mediaLink generato dal sistema.

Nota

Gli allegati sono una funzionalità legacy. Il supporto è ambito per offrire funzionalità continue se si usa già questa funzionalità.

Invece di usare allegati, è consigliabile usare Archiviazione BLOB di Azure come servizio di archiviazione BLOB predefinito per archiviare i dati BLOB. È possibile continuare a archiviare i metadati correlati ai BLOB, insieme ai collegamenti URI di riferimento, in Azure Cosmos DB come proprietà dell'elemento. L'archiviazione di questi dati in Azure Cosmos DB offre la possibilità di eseguire query sui metadati e i collegamenti ai BLOB archiviati in Archiviazione BLOB di Azure.

Microsoft si impegna a fornire un avviso minimo di 36 mesi prima di deprecare completamente gli allegati, che verranno annunciati in un'ulteriore data.

Limitazioni note

Gli allegati gestiti di Azure Cosmos DB sono distinti dal supporto per gli elementi standard, per i quali offre scalabilità illimitata, distribuzione globale e integrazione con altri servizi di Azure.

  • Gli allegati non sono supportati in tutte le versioni degli SDK di Azure Cosmos DB.
  • Gli allegati gestiti sono limitati a 2 GB di archiviazione per account di database.
  • Gli allegati gestiti non sono compatibili con la distribuzione globale di Azure Cosmos DB e non vengono replicati tra aree.

Nota

Azure Cosmos DB per MongoDB versione 3.2 usa allegati gestiti per GridFS e questi sono soggetti alle stesse limitazioni.

È consigliabile che gli sviluppatori usino la funzionalità GridFS mongoDB impostata per eseguire l'aggiornamento ad Azure Cosmos DB per MongoDB versione 3.6 o successiva, che è disaccoppiata dagli allegati e offre un'esperienza migliore. In alternativa, gli sviluppatori che usano il set di funzionalità GridFS di MongoDB devono considerare anche l'uso di Archiviazione BLOB di Azure, che è progettato per l'archiviazione di contenuto BLOB e offre funzionalità espanse a costi inferiori rispetto a GridFS.

Migrazione di allegati a Archiviazione BLOB di Azure

È consigliabile eseguire la migrazione degli allegati di Azure Cosmos DB a Archiviazione BLOB di Azure seguendo questa procedura:

  1. Copiare i dati degli allegati dal contenitore Azure Cosmos DB di origine al contenitore di Archiviazione BLOB di Azure di destinazione.
  2. Convalidare i dati BLOB caricati nel contenitore di Archiviazione BLOB di Azure di destinazione.
  3. Se applicabile, aggiungere riferimenti URI ai BLOB contenuti in Archiviazione BLOB di Azure come proprietà stringa all'interno del set di dati di Azure Cosmos DB.
  4. Eseguire il refactoring del codice dell'applicazione per leggere e scrivere BLOB dal nuovo contenitore Archiviazione BLOB di Azure.

Nell'esempio di codice seguente viene illustrato come copiare allegati da Azure Cosmos DB all'archiviazione BLOB di Azure come parte di un flusso di migrazione usando .NET SDK v2 di Azure Cosmos DB e Archiviazione BLOB di Azure .NET SDK v12. Assicurarsi di sostituire l'oggetto per l'account <placeholder values> Azure Cosmos DB di origine e il contenitore di archiviazione BLOB di Azure di destinazione.


using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

namespace attachments
{
    class Program
    {
        private static string cosmosAccount = "<Your_Azure_Cosmos_account_URI>";
        private static string cosmosKey = "<Your_Azure_Cosmos_account_PRIMARY_KEY>";
        private static string cosmosDatabaseName = "<Your_Azure_Cosmos_database>";
        private static string cosmosCollectionName = "<Your_Azure_Cosmos_collection>";
        private static string storageConnectionString = "<Your_Azure_Storage_connection_string>";
        private static string storageContainerName = "<Your_Azure_Storage_container_name>";
        private static DocumentClient cosmosClient = new DocumentClient(new Uri(cosmosAccount), cosmosKey);
        private static BlobServiceClient storageClient = new BlobServiceClient(storageConnectionString);
        private static BlobContainerClient storageContainerClient = storageClient.GetBlobContainerClient(storageContainerName);

        static void Main(string[] args)
        {
            CopyAttachmentsToBlobsAsync().Wait();
        }

        private async static Task CopyAttachmentsToBlobsAsync()
        {
            Console.WriteLine("Copying Azure Cosmos DB Attachments to Azure Blob Storage ...");

            int totalCount = 0;
            string docContinuation = null;

            // Iterate through each item (document in v2) in the Azure Cosmos DB container (collection in v2) to look for attachments.
            do
            {
                FeedResponse<dynamic> response = await cosmosClient.ReadDocumentFeedAsync(
                    UriFactory.CreateDocumentCollectionUri(cosmosDatabaseName, cosmosCollectionName),
                    new FeedOptions
                    {
                        MaxItemCount = -1,
                        RequestContinuation = docContinuation
                    });
                docContinuation = response.ResponseContinuation;

                foreach (Document document in response)
                {
                    string attachmentContinuation = null;
                    PartitionKey docPartitionKey = new PartitionKey(document.Id);

                    // Iterate through each attachment within the item (if any).
                    do
                    {
                        FeedResponse<Attachment> attachments = await cosmosClient.ReadAttachmentFeedAsync(
                            document.SelfLink,
                            new FeedOptions
                            {
                                PartitionKey = docPartitionKey,
                                RequestContinuation = attachmentContinuation
                            }
                        );
                        attachmentContinuation = attachments.ResponseContinuation;

                        foreach (var attachment in attachments)
                        {
                            // Download the attachment in to local memory.
                            MediaResponse content = await cosmosClient.ReadMediaAsync(attachment.MediaLink);

                            byte[] buffer = new byte[content.ContentLength];
                            await content.Media.ReadAsync(buffer, 0, buffer.Length);

                            // Upload the locally buffered attachment to blob storage
                            string blobId = String.Concat(document.Id, "-", attachment.Id);

                            Azure.Response<BlobContentInfo> uploadedBob = await storageContainerClient.GetBlobClient(blobId).UploadAsync(
                                new MemoryStream(buffer, writable: false),
                                true
                            );

                            Console.WriteLine("Copied attachment ... Item Id: {0} , Attachment Id: {1}, Blob Id: {2}", document.Id, attachment.Id, blobId);
                            totalCount++;

                            // Clean up attachment from Azure Cosmos DB.
                            // Warning: please verify you've succesfully migrated attachments to blog storage prior to cleaning up Azure Cosmos DB.
                            // await cosmosClient.DeleteAttachmentAsync(
                            //     attachment.SelfLink,
                            //     new RequestOptions { PartitionKey = docPartitionKey }
                            // );

                            // Console.WriteLine("Cleaned up attachment ... Document Id: {0} , Attachment Id: {1}", document.Id, attachment.Id);
                        }

                    } while (!string.IsNullOrEmpty(attachmentContinuation));
                }
            }
            while (!string.IsNullOrEmpty(docContinuation));

            Console.WriteLine("Finished copying {0} attachments to blob storage", totalCount);
        }
    }
}

Passaggi successivi