Ejercicio: lectura y consulta de elementos

Completado

Recuerde que se espera que la aplicación agregue elementos a un contenedor de Azure Cosmos DB for NoSQL y lea esos mismos elementos como validación. Llegados a este punto, la aplicación agrega correctamente elementos al contenedor. Hay dos formas clave de leer un elemento: realizando una lectura puntual o realizando una consulta.

Hay tres requisitos clave en este momento:

  1. Lectura puntual de un elemento mediante el identificador único y el valor de la clave de partición
  2. Creación de una consulta mediante una cadena de consulta simple
  3. Paginación de los resultados de la consulta mediante un iterador de fuente

Illustration of icons indicating data being queried using a query.

Después de completar este ejercicio, la aplicación casi estará lista. Tendrá consultas que pueden leer la categoría y los elementos de producto que creó anteriormente.

Lectura de punto de un elemento

La manera más sencilla de recuperar un elemento en Azure Cosmos DB es realizar una lectura puntual. Las lecturas puntuales usan un número pequeño y predecible de unidades de solicitud por segundo (US/s) en comparación con las consultas. Aquí se hace una lectura puntual del elemento de categoría individual helmets (cascos) que usted creó.

  1. Vuelva al archivo Program.cs.

  2. Cree una nueva instancia de PartitionKey para gear-climb-helmets.

    PartitionKey readKey = new("gear-climb-helmets");
    
  3. Use Container.ReadItemAsync para hacer una lectura puntual de un elemento específico mediante la propiedad id y el valor de la clave de partición.

    ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>(
        id: "91f79374-8611-4505-9c28-3bbbf1aa7df7",
        partitionKey: readKey
    );
    
  4. Obtenga el tipo genérico serializado mediante la propiedad Resource de la clase ItemResponse.

    Category readItem = readResponse.Resource;
    
  5. Muestre el identificador único y la carga de solicitudes de la operación de lectura puntual.

    Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");    
    
  6. Guarde el archivo Program.cs.

Ejecutar una consulta

En situaciones en las que necesite varios elementos, puede usar una consulta para buscar y recuperar esos elementos. Recuerde que usamos la propiedad de clave de partición categoryId para agrupar nuestros elementos en categorías específicas. Si se incluye esa propiedad en una consulta, se crea de forma eficaz una consulta con una única partición lógica. Ahora usará una consulta para buscar todos los elementos de la categoría tents (tiendas de campaña).

  1. En Program.cs, cree una cadena para la consulta SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents'. Sin embargo, use un parámetro denominado @partitionKey para el filtro categoryId.

    string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
    
  2. Cree una instancia de la clase QueryDefinition con la cadena de consulta.

    var query = new QueryDefinition(
        query: statement
    );
    
  3. Use el método fluido WithParameter para asignar el valor gear-camp-tents al parámetro @partitionKey.

    var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
    
  4. Use Container.GetItemQueryIterator<> para recuperar un iterador para su consulta específica.

    using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
        queryDefinition: parameterizedQuery
    );
    
  5. Escriba la consulta en la consola.

    Console.WriteLine($"[Start query]:\t{statement}");
    
  6. Guarde el archivo Program.cs.

Paginación de los resultados de la consulta

Azure Cosmos DB divide automáticamente los resultados de la consulta en páginas que se pueden recuperar de forma asincrónica. Para administrar estas páginas, debe escribir código en C# de forma específica para asegurarse de recuperar todas las páginas de resultados disponibles. Aquí, usará un bucle while y foreach en C# para recorrer en iteración las páginas de resultados.

  1. En Program.cs, Cree una nueva variable double denominada totalRequestCharge establecida en un valor de 0.

    double totalRequestCharge = 0d;
    
  2. Cree un bucle while que itere hasta que la propiedad FeedIterator.HasMoreResults del iterador de fuente sea false.

    while (feed.HasMoreResults)
    {
    }
    
  3. Dentro del bucle while, obtenga una nueva página de resultados mediante el método FeedIterator.ReadNextAsync.

    FeedResponse<Product> page = await feed.ReadNextAsync();
    
  4. Todavía dentro del bucle while, incremente el la carga total de solicitudes con el valor de FeedResponse.RequestCharge.

    totalRequestCharge += page.RequestCharge;
    
  5. Todavía dentro del bucle while, cree un nuevo bucle foreach para recorrer en iteración los elementos reales de la página.

    foreach (Product item in page)
    {
    }
    
  6. Dentro del bucle foreach, escriba en la consola las propiedades id y name del elemento devuelto.

    Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
    
  7. Fuera del bucle while, escriba en la consola la carga total de solicitudes que calculó.

    Console.WriteLine($"[Query metrics]:\t(RUs: {totalRequestCharge})");
    

    Sugerencia

    Si no está seguro de qué código debe estar dentro o fuera de los bucles while y foreach, vaya a la sección de revisar código en Comprobar el trabajo.

  8. Guarde el archivo Program.cs.

Comprobar el trabajo

La aplicación ahora lee y consulta elementos del contenedor. Aquí ejecutará la aplicación para observar los resultados de ambas operaciones.

  1. Ejecución de la aplicación .NET en el terminal:

    dotnet run
    
  2. Observe la salida de la ejecución de la aplicación. La salida debe coincidir con el ejemplo siguiente:

    ...
    [Point read item]:      91f79374-8611-4505-9c28-3bbbf1aa7df7    (RUs: 1)
    [Start query]:          SELECT * FROM products p WHERE p.categoryId = @partitionKey
    [Returned item]:        5df21ec5-813c-423e-9ee9-1a2aaead0be4    (Name: N/A)
    [Returned item]:        e8dddee4-9f43-4d15-9b08-0d7f36adcac8    (Name: Cirroa Tent)
    [Returned item]:        e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa    (Name: Kuloar Tent)
    [Returned item]:        f7653468-c4b8-47c9-97ff-451ee55f4fd5    (Name: Mammatin Tent)
    [Returned item]:        6e3b7275-57d4-4418-914d-14d1baca0979    (Name: Nimbolo Tent)
    [Query metrics]:        (RUs: 2.94)
    

    Sugerencia

    Las US/s que se muestran en esta salida de ejemplo pueden variar en su caso.

    ¿Ha observado que el elemento de categoría se deserializa correctamente en el tipo que usa para productos? Dado que el elemento de categoría no tenía una propiedad name, esa propiedad se dejó en su valor predeterminado. La comprobación de tipos, la administración de esquemas y la serialización o deserialización son todo lo que la aplicación puede administrar completamente del lado cliente.