Connettere un'applicazione Node.js Mongoose ad Azure Cosmos DB

SI APPLICA A: Mongodb

Questa esercitazione dimostra come usare il framework Mongoose quando si archiviano dati in Azure Cosmos DB. Per questa procedura dettagliata viene usata l'API di Azure Cosmos DB per MongoDB. Mongoose è un framework di modellazione a oggetti per MongoDB in Node.js che offre una soluzione semplice e basata su schemi per modellare i dati dell'applicazione.

Azure Cosmos DB è il servizio di database multi-modello distribuito globalmente di Microsoft. È possibile creare ed eseguire rapidamente query su database di documenti, coppie chiave-valore e grafi, sfruttando in ognuno dei casi i vantaggi offerti dalle funzionalità di scalabilità orizzontale e distribuzione globale alla base di Azure Cosmos DB.

Prerequisiti

Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.

È possibile provare gratuitamente Azure Cosmos DB, senza una sottoscrizione di Azure e senza alcun impegno richiesto. In alternativa, è possibile creare un account di livello gratuito di Azure Cosmos DB con le prime 1000 UR/s e 25 GB di spazio di archiviazione gratuitamente. È anche possibile usare l'emulatore di Azure Cosmos DB con un URI di https://localhost:8081. Per la chiave da usare con l'emulatore, vedere Autenticazione delle richieste.

Node.js v0.10.29 o versioni successive.

Creare un account Azure Cosmos DB

Creare prima di tutto un account Azure Cosmos DB. Se è già disponibile un account da usare, è possibile passare a Configurare l'applicazione Node.js. Se si usa l'emulatore Azure Cosmos DB, seguire i passaggi descritti in Emulatore di Azure Cosmos DB per configurare l'emulatore e proseguire con il passaggio Configurare l'applicazione Node.js.

  1. In una nuova finestra del browser accedere al portale di Azure.

  2. Nel menu a sinistra selezionare Crea una risorsa.

    Screenshot of creating a resource in the Azure portal.

  3. Nella pagina Nuovo selezionare Database>Azure Cosmos DB.

    Screenshot of the Azure portal Databases pane.

  4. Nella pagina Selezionare l'opzione API selezionare Azure Cosmos DB per MongoDB>Crea.

    L'API determina il tipo di account da creare. Selezionare Azure Cosmos DB per MongoDB perché verrà creata una raccolta che funziona con MongoDB in questa guida introduttiva. Per altre informazioni, vedere Panoramica di Azure Cosmos DB per MongoDB.

    Screenshot of the Select API option pane.

  5. Nella pagina Crea account Azure Cosmos DB immettere le impostazioni per il nuovo account Azure Cosmos DB.

    Impostazione valore Descrizione
    Subscription Nome della sottoscrizione Selezionare la sottoscrizione di Azure da usare per l'account Azure Cosmos DB.
    Gruppo di risorse Nome del gruppo di risorse Selezionare un gruppo di risorse oppure fare clic su Crea nuovo, quindi immettere un nome univoco per il nuovo gruppo di risorse.
    Account Name: Immettere un nome univoco Immettere un nome univoco per identificare l'account Azure Cosmos DB. L'URI dell'account sarà mongo.cosmos.azure.com e verrà aggiunto al nome dell'account univoco.

    Il nome dell'account può usare solo lettere minuscole, numeri e trattini (-) e deve avere una lunghezza compresa tra 3 e 44 caratteri.
    Titolo Area più vicina ai propri utenti Selezionare una posizione geografica in cui ospitare l'account Azure Cosmos DB. Usare la località più vicina agli utenti per offrire loro la massima velocità di accesso ai dati.
    Modalità di capacità Provisioning velocità effettiva o Serverless Selezionare Provisioning velocità effettiva per creare un account in modalità Provisioning velocità effettiva. Selezionare Serverless per creare un account in modalità Serverless.

    Nota: solo l'API per MongoDB versione 4.2, 4.0 e 3.6 sono supportate dagli account serverless. Se si sceglie la versione 3.2, l'account verrà forzato in modalità Provisioning velocità effettiva.
    Applicare lo sconto in base al livello gratuito di Azure Cosmos DB Applicare o non applicare Il livello gratuito di Azure Cosmos DB offre i primi 1000 UR/s e 25 GB di spazio di archiviazione gratuiti per account. Altre informazioni sul livello gratuito.
    Versione Scegliere la versione del server richiesta Azure Cosmos DB per MongoDB è compatibile con il server versione 4.2, 4.0, 3.6 e 3.2. È possibile aggiornare o effettuare il downgrade di un account dopo la creazione.

    Nota

    È possibile avere fino a un account Azure Cosmos DB del livello gratuito per ogni sottoscrizione di Azure ed è necessario acconsentire esplicitamente durante la creazione dell'account. Se l'opzione per l'applicazione dello sconto per il livello gratuito non è visualizzata, un altro account nella sottoscrizione è già stato abilitato per il livello gratuito.

    Screenshot of the new account page for Azure Cosmos DB.

  6. Nella scheda Distribuzione globale configurare i dettagli seguenti. Ai fini di questa guida introduttiva è possibile lasciare i valori predefiniti:

    Impostazione valore Descrizione
    Ridondanza geografica Disabilita Abilitare o disabilitare la distribuzione globale nell'account associando la propria area a un'altra area. È possibile aggiungere altre aree al proprio account in un secondo momento.
    Scritture in più aree Disabilita La funzionalità Scritture in più aree consente di sfruttare la velocità effettiva di cui è stato effettuato il provisioning per i database e i contenitori in tutto il mondo.

    Nota

    Le opzioni seguenti non sono disponibili se si seleziona Serverless come modalità di capacità:

    • Applica sconto livello gratuito
    • Ridondanza geografica
    • Scritture in più aree
  7. Facoltativamente, è possibile configurare i dettagli aggiuntivi nelle schede seguenti:

    • Rete: consente di configurare l'accesso da una rete virtuale.
    • Criteri di backup: consente di configurare i criteri di backup periodici o continui.
    • Crittografia: consente di usare una chiave gestita dal servizio o una chiave gestita dal cliente.
    • Tag: i tag sono coppie nome-valore che consentono di classificare le risorse e visualizzare dati di fatturazione consolidati tramite l'applicazione dello stesso tag a più risorse e gruppi di risorse.
  8. Selezionare Rivedi e crea.

  9. La creazione dell'account richiede alcuni minuti. Attendere che il portale visualizzi l'opzione Congratulazioni. La pagina dell'account Azure Cosmos DB per MongoDB è pronta .

    Screenshot of the Azure portal Notifications pane.

Creazione di un database

In questa applicazione verranno illustrati due modi per creare raccolte in Azure Cosmos DB:

  • Archiviazione di ogni modello a oggetti in una raccolta separata: è consigliabile creare un database con velocità effettiva dedicata. L'uso di questo modello di capacità offrirà una migliore efficienza dei costi.

    Node.js tutorial - Screenshot of the Azure portal, showing how to create a database in the Data Explorer for an Azure Cosmos DB account, for use with the Mongoose Node module

  • Archiviazione di tutti i modelli a oggetti in una singola raccolta di Azure Cosmos DB: se si preferisce archiviare tutti i modelli in una singola raccolta, è sufficiente creare un nuovo database senza selezionare l'opzione Provision Throughput (Velocità effettiva provisioning). L'uso di questo modello di capacità creerà ogni raccolta con la propria capacità di velocità effettiva per ogni modello a oggetti.

Dopo aver creato il database, si userà il nome nella COSMOSDB_DBNAME variabile di ambiente seguente.

Configurare l'applicazione Node.js

Nota

Se si desidera solo esaminare il codice di esempio senza configurare l'applicazione, clonare l'esempio usato per questa esercitazione e compilare l'applicazione Node.js Mongoose in Azure Cosmos DB.

  1. Per creare un'applicazione Node.js nella cartella scelta, eseguire questo comando in un prompt dei comandi del nodo.

    npm init

    Rispondere alle domande e il progetto sarà pronto per l'utilizzo.

  2. Aggiungere un nuovo file alla cartella e denominarlo index.js.

  3. Installare i pacchetti necessari usando una delle opzioni npm install seguenti:

    • Mongoose: npm install mongoose --save

    Nota

    Per altre informazioni sulla versione del server mongoose compatibile con la versione del server API per MongoDB, vedere Compatibilità di Mongoose.

    • Dotenv(se si vogliono caricare i segreti da un file con estensione env):Dotenv(if you'd like to load your secrets from an .env file): npm install dotenv --save

      Nota

      Il flag --save aggiunge la dipendenza al file package.json.

  4. Importare le dipendenze nel index.js file.

    var mongoose = require('mongoose');
    var env = require('dotenv').config();   //Use the .env file to load the variables
    
  5. Aggiungere il stringa di connessione di Azure Cosmos DB e il nome di Azure Cosmos DB al .env file. Sostituire i segnaposto {cosmos-account-name} e {dbname} con il nome dell'account e il nome del database di Azure Cosmos DB, senza i simboli di parentesi graffa.

    // You can get the following connection details from the Azure portal. You can find the details on the Connection string pane of your Azure Cosmos DB account.
    
    COSMOSDB_USER = "<Azure Cosmos DB account's user name, usually the database account name>"
    COSMOSDB_PASSWORD = "<Azure Cosmos DB account password, this is one of the keys specified in your account>"
    COSMOSDB_DBNAME = "<Azure Cosmos DB database name>"
    COSMOSDB_HOST= "<Azure Cosmos DB Host name>"
    COSMOSDB_PORT=10255
    
  6. Eseguire la connessione all'istanza di Azure Cosmos DB tramite il framework Mongoose, aggiungendo il codice seguente alla fine di index.js.

    mongoose.connect("mongodb://"+process.env.COSMOSDB_HOST+":"+process.env.COSMOSDB_PORT+"/"+process.env.COSMOSDB_DBNAME+"?ssl=true& replicaSet=globaldb", {
       auth: {
         username: process.env.COSMOSDB_USER,
         password: process.env.COSMOSDB_PASSWORD
       },
       useNewUrlParser: true,
       useUnifiedTopology: true,
       retryWrites: false
    })
    .then(() => console.log('Connection to CosmosDB successful'))
    .catch((err) => console.error(err));
    

    Nota

    In questo caso, le variabili di ambiente vengono caricate usando process.env. {variableName} usando il dotenv pacchetto npm.

    Dopo aver eseguito la connessione ad Azure Cosmos DB, è possibile avviare la configurazione dei modelli a oggetti in Mongoose.

Procedure consigliate per l'uso di Mongoose con Azure Cosmos DB

Per ogni modello creato, Mongoose crea una nuova raccolta. Questa soluzione è più adatta all'uso dell'opzione Velocità effettiva a livello di database, descritta in precedenza. Per usare una singola raccolta, è necessario usare i discriminatori di Mongoose. che rappresentano un meccanismo di ereditarietà degli schemi. I discriminatori consentono di disporre di più modelli con schemi sovrapposti nella stessa raccolta MongoDB sottostante.

È possibile archiviare vari modelli di dati nella stessa raccolta e quindi usare una clausola di filtro in fase di query per visualizzare solo i dati necessari. Esaminiamo ognuno dei modelli.

Una raccolta per modello a oggetti

Questa sezione illustra come eseguire tale operazione con l'API di Azure Cosmos DB per MongoDB. Questo metodo è l'approccio consigliato perché consente di controllare i costi e la capacità. Di conseguenza, la quantità di unità richiesta nel database non dipende dal numero di modelli a oggetti. Si tratta del modello operativo predefinito per Mongoose, quindi si potrebbe avere familiarità con questo.

  1. Aprire di nuovo index.js.

  2. Creare la definizione dello schema per 'Family' (Famiglia).

    const Family = mongoose.model('Family', new mongoose.Schema({
        lastName: String,
        parents: [{
            familyName: String,
            firstName: String,
            gender: String
        }],
        children: [{
            familyName: String,
            firstName: String,
            gender: String,
            grade: Number
        }],
        pets:[{
            givenName: String
        }],
        address: {
            country: String,
            state: String,
            city: String
        }
    }));
    
  3. Creare un oggetto per 'Family' (Famiglia).

    const family = new Family({
        lastName: "Volum",
        parents: [
            { firstName: "Thomas" },
            { firstName: "Mary Kay" }
        ],
        children: [
            { firstName: "Ryan", gender: "male", grade: 8 },
            { firstName: "Patrick", gender: "male", grade: 7 }
        ],
        pets: [
            { givenName: "Buddy" }
        ],
        address: { country: "USA", state: "WA", city: "Seattle" }
    });
    
  4. Salvare infine l'oggetto in Azure Cosmos DB. Verrà creata una raccolta.

    family.save((err, saveFamily) => {
        console.log(JSON.stringify(saveFamily));
    });
    
  5. Creare a questo punto un altro schema e un altro oggetto, ad esempio 'Vacation Destinations' (Destinazioni vacanze) che può essere interessante per le famiglie.

    1. Come in precedenza, creare lo schema.

      const VacationDestinations = mongoose.model('VacationDestinations', new mongoose.Schema({
       name: String,
       country: String
      }));
      
    2. Creare un oggetto di esempio e salvarlo. È possibile aggiungere più oggetti a questo schema.

      const vacaySpot = new VacationDestinations({
       name: "Honolulu",
       country: "USA"
      });
      
      vacaySpot.save((err, saveVacay) => {
       console.log(JSON.stringify(saveVacay));
      });
      
  6. Nel portale di Azure saranno a questo punto disponibili due raccolte create in Azure Cosmos DB.

    Node.js tutorial - Screenshot of the Azure portal, showing an Azure Cosmos DB account, with multiple collection names highlighted - Node database

  7. È infine possibile leggere i dati da Azure Cosmos DB. Poiché è stato usato il modello di funzionamento predefinito di Mongoose, le letture avvengono come di consueto in Mongoose.

    Family.find({ 'children.gender' : "male"}, function(err, foundFamily){
        foundFamily.forEach(fam => console.log("Found Family: " + JSON.stringify(fam)));
    });
    

Utilizzo dei discriminatori di Mongoose per archiviare i dati in una singola raccolta

Per questo metodo si usano i discriminatori di Mongoose per ottimizzare i costi di ogni raccolta. I discriminatori consentono di definire una chiave ('Key') di differenziazione, che consente di eseguire operazioni di archiviazione, differenziazione e filtro su modelli a oggetti diversi.

In questo caso, si creerà un modello a oggetti di base, si definirà una chiave di differenziazione e si aggiungeranno 'Family' e 'VacationDestinations' come estensione del modello di base.

  1. Definire la configurazione di base e la chiave discriminatore.

    const baseConfig = {
        discriminatorKey: "_type", //If you've got a lot of different data types, you could also consider setting up a secondary index here.
        collection: "alldata"   //Name of the Common Collection
    };
    
  2. Definire quindi il modello a oggetti comune.

    const commonModel = mongoose.model('Common', new mongoose.Schema({}, baseConfig));
    
  3. Definire a questo punto il modello 'Family'. Si noti che in questo caso viene usato commonModel.discriminator anziché mongoose.model. Si aggiungerà inoltre la configurazione di base allo schema mongoose. La chiave discriminatore (discriminatorKey) in questo caso è FamilyType.

    const Family_common = commonModel.discriminator('FamilyType', new     mongoose.Schema({
        lastName: String,
        parents: [{
            familyName: String,
            firstName: String,
            gender: String
        }],
        children: [{
            familyName: String,
            firstName: String,
           gender: String,
            grade: Number
        }],
        pets:[{
            givenName: String
        }],
        address: {
            country: String,
            state: String,
            city: String
        }
    }, baseConfig));
    
  4. Analogamente, procedere con l'aggiunta di un altro schema, questa volta per 'VacationDestinations'. La chiave discriminatore (discriminatorKey) in questo caso è VacationDestinationsType.

    const Vacation_common = commonModel.discriminator('VacationDestinationsType', new mongoose.Schema({
        name: String,
        country: String
    }, baseConfig));
    
  5. Creare infine gli oggetti per il modello ed eseguire il salvataggio.

    1. Aggiungere uno o più oggetti al modello 'Family'.

      const family_common = new Family_common({
       lastName: "Volum",
       parents: [
           { firstName: "Thomas" },
           { firstName: "Mary Kay" }
       ],
       children: [
           { firstName: "Ryan", gender: "male", grade: 8 },
           { firstName: "Patrick", gender: "male", grade: 7 }
       ],
       pets: [
           { givenName: "Buddy" }
       ],
       address: { country: "USA", state: "WA", city: "Seattle" }
      });
      
      family_common.save((err, saveFamily) => {
       console.log("Saved: " + JSON.stringify(saveFamily));
      });
      
    2. Successivamente, aggiungere uno o più oggetti al modello 'VacationDestinations' ed eseguire il salvataggio.

      const vacay_common = new Vacation_common({
       name: "Honolulu",
       country: "USA"
      });
      
      vacay_common.save((err, saveVacay) => {
       console.log("Saved: " + JSON.stringify(saveVacay));
      });
      
  6. Passando di nuovo al portale di Azure, si noterà che è disponibile una sola raccolta denominata alldata con i dati di 'Family' e 'VacationDestinations'.

    Node.js tutorial - Screenshot of the Azure portal, showing an Azure Cosmos DB account, with the collection name highlighted - Node database

  7. Si noti inoltre che ogni oggetto dispone di un altro attributo denominato __type, che consente la differenziazione dei due diversi modelli a oggetti.

  8. Leggere infine i dati archiviati in Azure Cosmos DB. Mongoose filtrerà i dati in base al modello. Non sarà pertanto necessario eseguire altre operazioni durante la lettura dei dati. Sarà sufficiente specificare il modello (in questo caso, Family_common) e Mongoose gestirà l'applicazione dei filtri in base a 'DiscriminatorKey'.

    Family_common.find({ 'children.gender' : "male"}, function(err, foundFamily){
        foundFamily.forEach(fam => console.log("Found Family (using discriminator): " + JSON.stringify(fam)));
    });
    

Usare i discriminatori di Mongoose è molto facile. Pertanto, se si dispone di un'app che usa il framework Mongoose, questa esercitazione è un modo per rendere operativa l'applicazione usando l'API di Azure Cosmos DB per MongoDB senza dover apportare troppe modifiche.

Pulire le risorse

Dopo aver completato le operazioni con l'app e l'account Azure Cosmos DB, è possibile eliminare le risorse di Azure create in modo da non incorrere in altri costi. Per eliminare le risorse:

  1. Nella barra di ricerca del portale di Azure cercare e selezionare Gruppi di risorse.

  2. Selezionare nell'elenco il gruppo di risorse creato in questa guida di avvio rapido.

    Select the resource group to delete

  3. Nella pagina Panoramica del gruppo di risorse selezionare Elimina gruppo di risorse.

    Delete the resource group

  4. Nella finestra successiva immettere il nome del gruppo di risorse da eliminare e quindi selezionare Elimina.

Passaggi successivi