Inicio rápido: Conexión de una aplicación Go a Azure Cosmos DB for MongoDB

SE APLICA A: MongoDB

Azure Cosmos DB es un servicio de base de datos multimodelo que permite crear y consultar rápidamente bases de datos de documentos, tablas, claves-valores y grafos con funcionalidades de distribución global y escala horizontal. En este inicio rápido, se va a crear y administrar una cuenta de Azure Cosmos DB mediante Azure Cloud Shell, se va a clonar una aplicación de ejemplo existente desde GitHub y se va a configurar esta para que funcione con Azure Cosmos DB.

La aplicación de ejemplo es una herramienta de administración todo de línea de comandos escrita en Go. La API de Azure Cosmos DB para MongoDB es compatible con el protocolo de conexión de MongoDB, lo que permite que cualquier controlador cliente de MongoDB se conecte a ella. Esta aplicación usa el controlador de Go para MongoDB de una manera transparente, de forma que sabe que los datos se almacenan en una base de datos de Azure Cosmos DB.

Requisitos previos

Clonación de la aplicación de ejemplo

Ejecute los comandos siguientes para clonar el repositorio de ejemplo.

  1. Abra un símbolo del sistema, cree una carpeta denominada git-samples y, después, cierre el símbolo del sistema.

    mkdir "C:\git-samples"
    
  2. Abra una ventana de terminal de Git, como git bash y utilice el comando cd para cambiar a la nueva carpeta para instalar la aplicación de ejemplo.

    cd "C:\git-samples"
    
  3. Ejecute el comando siguiente para clonar el repositorio de ejemplo. Este comando crea una copia de la aplicación de ejemplo en el equipo.

    git clone https://github.com/Azure-Samples/cosmosdb-go-mongodb-quickstart
    

Revisión del código

Este paso es opcional. Si le interesa saber cómo funciona la aplicación, puede revisar los siguientes fragmentos de código. En caso contrario, puede ir directamente a Ejecutar la aplicación. El diseño de la aplicación es el siguiente:

.
├── go.mod
├── go.sum
└── todo.go

Los fragmentos de código siguientes se han tomado del archivo todo.go.

Conexión de una aplicación Go a Azure Cosmos DB

clientOptions encapsula la cadena de conexión de Azure Cosmos DB, que se pasa mediante una variable de entorno (se pueden encontrar los detalles en la próxima sección). La conexión se inicializa mediante mongo.NewClient al que se pasa la instancia clientOptions. Se invoca la función Ping para confirmar que la conectividad es correcta (es una estrategia con respuesta rápida a errores).

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    defer cancel()

    clientOptions := options.Client().ApplyURI(mongoDBConnectionString).SetDirect(true)
    
    c, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        log.Fatalf("unable to initialize connection %v", err)
    }

    err = c.Ping(ctx, nil)
    if err != nil {
        log.Fatalf("unable to connect %v", err)
    }

Nota:

El uso de la configuración de SetDirect(true) es importante, ya que sin ella obtendrá el siguiente error de conectividad: unable to connect connection(cdb-ms-prod-<azure-region>-cm1.documents.azure.com:10255[-4]) connection is closed.

Creación de un elemento todo

Para crear un elemento todo, se obtiene un identificador para mongo.Collection y se invoca la función InsertOne.

func create(desc string) {
    c := connect()
    ctx := context.Background()
    defer c.Disconnect(ctx)

    todoCollection := c.Database(database).Collection(collection)
    r, err := todoCollection.InsertOne(ctx, Todo{Description: desc, Status: statusPending})
    if err != nil {
        log.Fatalf("failed to add todo %v", err)
    }

Se pasa un struct Todo que contiene la descripción y el estado (que se establece inicialmente en pending):

type Todo struct {
    ID          primitive.ObjectID `bson:"_id,omitempty"`
    Description string             `bson:"description"`
    Status      string             `bson:"status"`
}

Enumeración de elementos todo

Se pueden enumerar los elementos TODO según unos criterios. Se crea un objeto bson.D para encapsular los criterios de filtro:

func list(status string) {
    .....
    var filter interface{}
    switch status {
    case listAllCriteria:
        filter = bson.D{}
    case statusCompleted:
        filter = bson.D{{statusAttribute, statusCompleted}}
    case statusPending:
        filter = bson.D{{statusAttribute, statusPending}}
    default:
        log.Fatal("invalid criteria for listing todo(s)")
    }

Se usa Find para buscar documentos según el filtro y el resultado se convierte en un sector de Todo

    todoCollection := c.Database(database).Collection(collection)
    rs, err := todoCollection.Find(ctx, filter)
    if err != nil {
        log.Fatalf("failed to list todo(s) %v", err)
    }
    var todos []Todo
    err = rs.All(ctx, &todos)
    if err != nil {
        log.Fatalf("failed to list todo(s) %v", err)
    }

Por último, la información se representa en formato tabular:

    todoTable := [][]string{}

    for _, todo := range todos {
        s, _ := todo.ID.MarshalJSON()
        todoTable = append(todoTable, []string{string(s), todo.Description, todo.Status})
    }

    table := tablewriter.NewWriter(os.Stdout)
    table.SetHeader([]string{"ID", "Description", "Status"})

    for _, v := range todoTable {
        table.Append(v)
    }
    table.Render()

Actualización de un elemento todo

Un elemento todo se puede actualizar en función de su valor de _id. Se crea un filtro bson.D basado en el valor de _id y otro para la información actualizada, que tiene un nuevo estado (completed o pending) en este caso. Por último, se invoca la función UpdateOne con el filtro y el documento actualizado:

func update(todoid, newStatus string) {
....
    todoCollection := c.Database(database).Collection(collection)
    oid, err := primitive.ObjectIDFromHex(todoid)
    if err != nil {
        log.Fatalf("failed to update todo %v", err)
    }
    filter := bson.D{{"_id", oid}}
    update := bson.D{{"$set", bson.D{{statusAttribute, newStatus}}}}
    _, err = todoCollection.UpdateOne(ctx, filter, update)
    if err != nil {
        log.Fatalf("failed to update todo %v", err)
    }

Eliminación de un elemento todo

Un elemento todo se elimina según su valor de _id y se encapsula en forma de una instancia bson.D. Se invoca a DeleteOne para eliminar el documento.

func delete(todoid string) {
....
    todoCollection := c.Database(database).Collection(collection)
    oid, err := primitive.ObjectIDFromHex(todoid)
    if err != nil {
        log.Fatalf("invalid todo ID %v", err)
    }
    filter := bson.D{{"_id", oid}}
    _, err = todoCollection.DeleteOne(ctx, filter)
    if err != nil {
        log.Fatalf("failed to delete todo %v", err)
    }
}

Compilar la aplicación

Cambie al directorio en el que ha clonado la aplicación y compílela (mediante go build).

cd monogdb-go-quickstart
go build -o todo

Para confirmar que la aplicación se compiló correctamente:

./todo --help

Configuración de Azure Cosmos DB

Inicio de sesión en Azure

Si decide instalar y usar la CLI localmente, para este tema es preciso que ejecute la CLI de Azure, versión 2.0 o posterior. Ejecute az --version para encontrar la versión. Si necesita instalarla o actualizarla, consulte [Instalación de la CLI de Azure].

Si usa una CLI de Azure instalada, inicie sesión en la suscripción de Azure con el comando az login y siga las instrucciones de la pantalla. Puede omitir este paso si usa Azure Cloud Shell.

az login 

Agregar el módulo de Azure Cosmos DB

Si va a usar una CLI de Azure instalada, ejecute el comando az para comprobar si el componente cosmosdb ya está instalado. Si cosmosdb está en la lista de comandos de referencia, continúe con el comando siguiente. Puede omitir este paso si usa Azure Cloud Shell.

Si cosmosdb no está en la lista de comandos de referencia, vuelva a instalar la CLI de Azure.

Crear un grupo de recursos

Cree un grupo de recursos con el comando az group create. Un grupo de recursos de Azure es un contenedor lógico en el que se implementan y administran recursos de Azure como aplicaciones web, bases de datos y cuentas de almacenamiento.

En el ejemplo siguiente se crea un grupo de recursos en la región de Oeste de Europa. Elija un nombre único para el grupo de recursos.

Si usa Azure Cloud Shell, seleccione Probarlo, siga las indicaciones de la pantalla para iniciar sesión y, a continuación, copie el comando en el símbolo del sistema.

az group create --name myResourceGroup --location "West Europe"

Creación de una cuenta de Azure Cosmos DB

Cree una cuenta de Azure Cosmos DB con el comando az cosmosdb create.

En el comando siguiente, sustituya su propio nombre único de la cuenta de Azure Cosmos DB donde vea el marcador de posición <cosmosdb-name>. Este nombre único se usará como parte del punto de conexión de Azure Cosmos DB (https://<cosmosdb-name>.documents.azure.com/), por lo que debe ser único entre todas las cuentas de Azure Cosmos DB de Azure.

az cosmosdb create --name <cosmosdb-name> --resource-group myResourceGroup --kind MongoDB

El parámetro --kind MongoDB habilita las conexiones de cliente de MongoDB.

Cuando se crea la cuenta de Azure Cosmos DB, la CLI de Azure muestra información similar a la del ejemplo siguiente.

Nota:

Este ejemplo usa JSON como el formato de salida de la CLI de Azure, que es el valor predeterminado. Para usar otro formato de salida, consulte Formatos de salida para los comandos de la CLI de Azure.

{
  "databaseAccountOfferType": "Standard",
  "documentEndpoint": "https://<cosmosdb-name>.documents.azure.com:443/",
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Document
DB/databaseAccounts/<cosmosdb-name>",
  "kind": "MongoDB",
  "location": "West Europe",
  "name": "<cosmosdb-name>",
  "readLocations": [
    {
      "documentEndpoint": "https://<cosmosdb-name>-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "<cosmosdb-name>-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ],
  "resourceGroup": "myResourceGroup",
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "writeLocations": [
    {
      "documentEndpoint": "https://<cosmosdb-name>-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "<cosmosdb-name>-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ]
} 

Recuperación de la clave de base de datos

Para conectarse a una base de datos de Azure Cosmos DB, necesita la clave de base de datos. Use el comando az cosmosdb keys list para recuperar la clave principal.

az cosmosdb keys list --name <cosmosdb-name> --resource-group myResourceGroup --query "primaryMasterKey"

La CLI de Azure genera información similar a la del ejemplo siguiente.

"RUayjYjixJDWG5xTqIiXjC..."

Configuración de la aplicación

Exporte la cadena de conexión, la base de datos de MongoDB y los nombres de colección como variables de entorno.

export MONGODB_CONNECTION_STRING="mongodb://<COSMOSDB_ACCOUNT_NAME>:<COSMOSDB_PASSWORD>@<COSMOSDB_ACCOUNT_NAME>.documents.azure.com:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&appName=@<COSMOSDB_ACCOUNT_NAME>@"

Nota:

La opción ssl=true es importante debido a los requisitos de Azure Cosmos DB. Para más información, consulte Requisitos de la cadena de conexión.

En la variable de entorno MONGODB_CONNECTION_STRING, reemplace los marcadores de posición de <COSMOSDB_ACCOUNT_NAME> y <COSMOSDB_PASSWORD>.

  1. <COSMOSDB_ACCOUNT_NAME>: el nombre de la cuenta de Azure Cosmos DB que ha creado.
  2. <COSMOSDB_PASSWORD>: la clave de base de datos extraída en el paso anterior.
export MONGODB_DATABASE=todo-db
export MONGODB_COLLECTION=todos

Puede elegir los valores que prefiera para MONGODB_DATABASE y MONGODB_COLLECTION o dejarlos como están.

Ejecución de la aplicación

Para crear un elemento todo:

./todo --create "Create an Azure Cosmos DB database account"

Si la operación es correcta, verá una salida con el valor de _id de MongoDB del documento recién creado:

added todo ObjectID("5e9fd6befd2f076d1f03bd8a")

Creación de otro elemento todo:

./todo --create "Get the MongoDB connection string using the Azure CLI"

Enumeración de todos los elementos todo:

./todo --list all

Verá los que acaba de agregar en formato tabular:

+----------------------------+--------------------------------+-----------+
|             ID             |          DESCRIPTION           |  STATUS   |
+----------------------------+--------------------------------+-----------+
| "5e9fd6b1bcd2fa6bd267d4c4" | Create an Azure Cosmos DB      | pending   |
|                            | database account               |           |
| "5e9fd6befd2f076d1f03bd8a" | Get the MongoDB connection     | pending   |
|                            | string using the Azure CLI     |           |
+----------------------------+--------------------------------+-----------+

Para actualizar el estado de un elemento todo (por ejemplo, cambiarlo al estado completed), use el identificador de todo:

./todo --update 5e9fd6b1bcd2fa6bd267d4c4,completed

Enumeración de solo los elementos todo completados:

./todo --list completed

Verá el que acaba de actualizar:

+----------------------------+--------------------------------+-----------+
|             ID             |          DESCRIPTION           |  STATUS   |
+----------------------------+--------------------------------+-----------+
| "5e9fd6b1bcd2fa6bd267d4c4" | Create an Azure Cosmos DB      | completed |
|                            | database account               |           |
+----------------------------+--------------------------------+-----------+

Ver datos en el Explorador de datos

Los datos almacenados en una instancia de Azure Cosmos DB se pueden ver y consultar en Azure Portal.

Para ver y consultar los datos de usuario creados en el paso anterior y trabajar con ellos, inicie sesión en Azure Portal en el explorador web.

En el cuadro de búsqueda superior, escriba Azure Cosmos DB. Cuando se abra la hoja de la cuenta de Azure Cosmos DB, seleccione su cuenta de Azure Cosmos DB. En el panel de navegación izquierdo, seleccione Explorador de datos. Expanda la colección en el panel Colecciones. Ahora puede ver los documentos de la colección, consultar los datos e incluso crear y ejecutar procedimientos almacenados, desencadenadores y UDF.

El Explorador de datos muestra el documento recién creado

Eliminación de un elemento todo mediante su identificador:

./todo --delete 5e9fd6b1bcd2fa6bd267d4c4,completed

Enumeración de los elementos todo que se van a confirmar:

./todo --list all

El elemento todo que acaba de eliminar no debe estar presente:

+----------------------------+--------------------------------+-----------+
|             ID             |          DESCRIPTION           |  STATUS   |
+----------------------------+--------------------------------+-----------+
| "5e9fd6befd2f076d1f03bd8a" | Get the MongoDB connection     | pending   |
|                            | string using the Azure CLI     |           |
+----------------------------+--------------------------------+-----------+

Limpieza de recursos

Cuando haya terminado tanto con la aplicación como con la cuenta de Azure Cosmos DB, puede eliminar los recursos de Azure que creó para no tener más gastos. Para eliminar los recursos:

  1. En la barra de búsqueda de Azure Portal, busque y seleccione Grupos de recursos.

  2. En la lista, seleccione el grupo de recursos que creó para este inicio rápido.

    Selección del grupo de recursos que se eliminará

  3. En la página Información general del grupo de recursos, seleccione Eliminar grupo de recursos.

    Eliminar el grupo de recursos

  4. En la ventana siguiente, escriba el nombre del grupo de recursos que desea eliminar y, después, seleccione Eliminar.

Pasos siguientes

En este inicio rápido, ha aprendido a crear una cuenta de Azure Cosmos DB for MongoDB mediante Azure Cloud Shell, y a crear y ejecutar una aplicación Go de línea de comandos para administrar elementos todo. Ahora puede importar datos adicionales en la cuenta de Azure Cosmos DB.

¿Intenta planear la capacidad de una migración a Azure Cosmos DB? Para ello, puede usar información sobre el clúster de bases de datos existente.