Condividi tramite


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 standard di Azure Cosmos DB.
  • 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. L'ambito del supporto è offrire funzionalità continue se si usa già questa funzionalità.

Anziché usare gli allegati, è consigliabile usare Archiviazione BLOB di Azure come servizio di archiviazione BLOB appositamente creato 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à degli elementi. L'archiviazione di questi dati in Azure Cosmos DB consente di eseguire query sui metadati e i collegamenti ai BLOB archiviati in Archiviazione BLOB di Azure.

Microsoft si impegna a fornire un preavviso minimo di 36 mesi prima di deprecare completamente gli allegati, che verranno annunciati a 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 spazio di archiviazione per ogni 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 sono soggetti alle stesse limitazioni.

È consigliabile che gli sviluppatori usino il set di funzionalità di MongoDB GridFS per eseguire l'aggiornamento ad Azure Cosmos DB per MongoDB versione 3.6 o successiva, che è separato dagli allegati e offre un'esperienza migliore. In alternativa, gli sviluppatori che usano il set di funzionalità GridFS di MongoDB devono prendere in considerazione anche l'uso di Archiviazione BLOB di Azure, che è progettato per archiviare contenuto BLOB e offre funzionalità espanse a un costo inferiore rispetto a GridFS.

Migrazione di allegati ad Archiviazione BLOB di Azure

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

  1. Copiare i dati degli allegati dal contenitore di Azure Cosmos DB di origine nel 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. Effettuare il refactoring del codice dell'applicazione per leggere e scrivere BLOB dal nuovo contenitore di Archiviazione BLOB di Azure.

L'esempio di codice seguente illustra come copiare gli allegati da Azure Cosmos DB all'archivio BLOB di Azure come parte di un flusso di migrazione usando .NET SDK v2 di Azure Cosmos DB e .NET SDK di Archiviazione BLOB di Azure v12. Assicurarsi di sostituire <placeholder values> per l'account 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