Eventos
Compilación de Intelligent Apps
17 mar, 21 - 21 mar, 10
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Regístrese ahoraEste explorador ya no se admite.
Actualice a Microsoft Edge para aprovechar las características y actualizaciones de seguridad más recientes, y disponer de soporte técnico.
SE APLICA A: NoSQL
Los datos geoespaciales de Azure Cosmos DB for NoSQL permiten almacenar información de la ubicación y realizar consultas comunes, entre las que se incluyen, entre otras:
En esta guía se explica el proceso de creación de datos geoespaciales, la indexación de los datos y la consulta de los datos en un contenedor.
az login
.Todos los contenedores incluyen una directiva de indexación predeterminada que indexará correctamente los datos geoespaciales. Para crear una directiva de indexación personalizada, cree una cuenta y especifique un archivo JSON con la configuración de la directiva. En esta sección, se usa un índice espacial personalizado para un contenedor recién creado.
Abra un terminal.
Cree una variable de shell para el nombre de la cuenta y el grupo de recursos de Azure Cosmos DB for NoSQL.
# Variable for resource group name
resourceGroupName="<name-of-your-resource-group>"
# Variable for account name
accountName="<name-of-your-account>"
Cree una base de datos denominada cosmicworks
mediante az cosmosdb sql database create
.
az cosmosdb sql database create \
--resource-group "<resource-group-name>" \
--account-name "<nosql-account-name>" \
--name "cosmicworks" \
--throughput 400
Cree un nuevo archivo JSON denominado index-policy.json y agregue el siguiente objeto JSON al archivo.
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
],
"spatialIndexes": [
{
"path": "/location/*",
"types": [
"Point",
"Polygon"
]
}
]
}
Use az cosmosdb sql container create
para crear un contenedor denominado locations
con una ruta de acceso de clave de partición de /region
.
az cosmosdb sql container create \
--resource-group "<resource-group-name>" \
--account-name "<nosql-account-name>" \
--database-name "cosmicworks" \
--name "locations" \
--partition-key-path "/category" \
--idx @index-policy.json
Por último, obtenga el punto de conexión de la cuenta mediante az cosmosdb show
y una consulta JMESPath.
az cosmosdb show \
--resource-group "<resource-group-name>" \
--name "<nosql-account-name>" \
--query "documentEndpoint"
Registre el punto de conexión de la cuenta, ya que lo necesitará en la sección siguiente.
El SDK de .NET para Azure Cosmos DB for NoSQL proporciona clases para objetos GeoJSON comunes. Use este SDK para simplificar el proceso de agregar objetos geográficos al contenedor.
Abra un terminal en un directorio vacío.
Cree una nueva aplicación .NET mediante el comando dotnet new
con la plantilla console.
dotnet new console
Importe el Microsoft.Azure.Cosmos
paquete NuGet mediante el comando dotnet add package
.
dotnet add package Microsoft.Azure.Cosmos --version 3.*
Advertencia
Entity Framework no tiene actualmente datos espaciales en Azure Cosmos DB for NoSQL. Use uno de los SDK de Azure Cosmos DB for NoSQL para admitir GeoJSON fuertemente tipado.
Importe el Azure.Identity
paquete NuGet.
dotnet add package Azure.Identity --version 1.*
Compile el proyecto con el comando dotnet build
.
dotnet build
Abra el entorno de desarrollador integrado (IDE) que prefiera en el mismo directorio que la aplicación de consola de .NET.
Abra el archivo Program.cs recién creado y elimine cualquier código existente. Agregue mediante directivas para los espacios de nombres Microsoft.Azure.Cosmos
, Microsoft.Azure.Cosmos.Linq
y Microsoft.Azure.Cosmos.Spatial
.
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Azure.Cosmos.Spatial;
Agregue otra directiva using para el espacio de nombres Azure.Identity
.
using Azure.Identity;
Cree una nueva variable denominada credential
de tipo DefaultAzureCredential
.
DefaultAzureCredential credential = new();
Cree una variable de cadena denominada endpoint
con el punto de conexión de la cuenta de Azure Cosmos DB para NoSQL.
string endpoint = "<nosql-account-endpoint>";
Cree una nueva instancia de la clase CosmosClient
que pasa en connectionString
y encapsúlela en una instrucción using.
using CosmosClient client = new (connectionString);
Recupere una referencia al contenedor creado anteriormente (cosmicworks/locations
) en la cuenta de Azure Cosmos DB for NoSQL mediante CosmosClient.GetDatabase
y, a continuación, Database.GetContainer
. Almacene el resultado en una variable denominada container
.
var container = client.GetDatabase("cosmicworks").GetContainer("locations");
Guarde el archivo Program.cs.
El SDK de .NET incluye varios tipos en el espacio de nombres Microsoft.Azure.Cosmos.Spatial
para representar objetos GeoJSON comunes. Estos tipos simplifican el proceso de agregar nueva información de ubicación a los elementos de un contenedor.
Cree un nuevo archivo llamado Office.cs. En el archivo, agregue una directiva using a Microsoft.Azure.Cosmos.Spatial
y, a continuación, cree unOffice
tipo de registro con estas propiedades:
Tipo | Descripción | Valor predeterminado | |
---|---|---|---|
id | string |
Identificador único | |
name | string |
Nombre de la oficina | |
ubicación | Point |
Punto geográfico GeoJSON | |
category | string |
Valor de la clave de partición | business-office |
using Microsoft.Azure.Cosmos.Spatial;
public record Office(
string id,
string name,
Point location,
string category = "business-office"
);
Nota
Este registro incluye una propiedad Point
que representa una posición específica en GeoJSON. Para obtener más información, consulte Punto GeoJSON.
Cree otro archivo denominado Region.cs. Agregue otro tipo de registro denominado Region
con estas propiedades:
Tipo | Descripción | Valor predeterminado | |
---|---|---|---|
id | string |
Identificador único | |
name | string |
Nombre de la oficina | |
ubicación | Polygon |
Forma geográfica de GeoJSON | |
category | string |
Valor de la clave de partición | business-region |
using Microsoft.Azure.Cosmos.Spatial;
public record Region(
string id,
string name,
Polygon location,
string category = "business-region"
);
Nota
Este registro incluye una propiedad Polygon
que representa una forma compuesta de líneas dibujadas entre varias ubicaciones en GeoJSON. Para obtener más información, consulte Polígono GeoJSON.
Cree otro archivo denominado Result.cs. Agregue un tipo de registro denominado Result
con estas dos propiedades:
Tipo | Descripción | |
---|---|---|
name | string |
Nombre del resultado coincidente |
distanceKilometers | decimal |
Distancia en kilómetros |
public record Result(
string name,
decimal distanceKilometers
);
Guarde los archivos Office.cs, Region.cs y Result.cs.
Abra de nuevo el archivo Program.cs.
Cree un nuevo Polygon
en una variable denominada mainCampusPolygon
.
Polygon mainCampusPolygon = new (
new []
{
new LinearRing(new [] {
new Position(-122.13237, 47.64606),
new Position(-122.13222, 47.63376),
new Position(-122.11841, 47.64175),
new Position(-122.12061, 47.64589),
new Position(-122.13237, 47.64606),
})
}
);
Cree una variable Region
denominada mainCampusRegion
con el polígono, el identificador único 1000
y el nombre Main Campus
.
Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
Use Container.UpsertItemAsync
para agregar la región al contenedor. Escriba la información de la región en la consola.
await container.UpsertItemAsync<Region>(mainCampusRegion);
Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");
Sugerencia
En esta guía se usa upsert en lugar de insertar para que pueda ejecutar el script varias veces sin causar un conflicto entre los identificadores únicos. Para obtener más información sobre las operaciones upsert, consulte creación de elementos.
Crear una nueva variable Point
llamada headquartersPoint
. Use esa variable para crear una variable Office
denominada headquartersOffice
con el punto, el identificador único 0001
y el nombre Headquarters
.
Point headquartersPoint = new (-122.12827, 47.63980);
Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
Cree otra variable Point
denominada researchPoint
. Use esa variable para crear otra variable Office
denominada researchOffice
con su correspondiente punto, el identificador único 0002
y el nombre Research and Development
.
Point researchPoint = new (-96.84369, 46.81298);
Office researchOffice = new ("0002", "Research and Development", researchPoint);
Cree un objeto TransactionalBatch
para upsert ambas variables Office
como una sola transacción. A continuación, escriba la información de ambas oficinas en la consola.
TransactionalBatch officeBatch = container.CreateTransactionalBatch(new PartitionKey("business-office"));
officeBatch.UpsertItem<Office>(headquartersOffice);
officeBatch.UpsertItem<Office>(researchOffice);
await officeBatch.ExecuteAsync();
Console.WriteLine($"[UPSERT ITEM]\t{headquartersOffice}");
Console.WriteLine($"[UPSERT ITEM]\t{researchOffice}");
Nota
Para obtener más información sobre las transacciones, consulte Operaciones por lotes transaccionales.
Guarde el archivo Program.cs.
Ejecute la aplicación en un terminal mediante dotnet run
. Observe que la salida de la ejecución de la aplicación incluye información sobre los tres elementos recién creados.
dotnet run
[UPSERT ITEM] Region { id = 1000, name = Main Campus, location = Microsoft.Azure.Cosmos.Spatial.Polygon, category = business-region }
[UPSERT ITEM] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
[UPSERT ITEM] Office { id = 0002, name = Research and Development, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Los tipos del espacio de nombres Microsoft.Azure.Cosmos.Spatial
se pueden usar como entradas para que una consulta con parámetros NoSQL use funciones integradas como ST_DISTANCE
.
Abra el archivo Program.cs.
Cree una variable string
denominada nosql
con la consulta para medir la distancia entre puntos.
string nosqlString = @"
SELECT
o.name,
NumberBin(distanceMeters / 1000, 0.01) AS distanceKilometers
FROM
offices o
JOIN
(SELECT VALUE ROUND(ST_DISTANCE(o.location, @compareLocation))) AS distanceMeters
WHERE
o.category = @partitionKey AND
distanceMeters > @maxDistance
";
Sugerencia
Esta consulta coloca la función geoespacial dentro de una subconsulta para simplificar el proceso de reutilización del valor ya calculado varias veces en las cláusulas SELECT
y WHERE
.
Cree una variable QueryDefinition
denominada query
con la variable nosqlString
como parámetro. A continuación, use el método fluent QueryDefinition.WithParameter
varias veces para agregar estos parámetros a la consulta:
Value | |
---|---|
@maxDistance | 2000 |
@partitionKey | "business-office" |
@compareLocation | new Point(-122.11758, 47.66901) |
var query = new QueryDefinition(nosqlString)
.WithParameter("@maxDistance", 2000)
.WithParameter("@partitionKey", "business-office")
.WithParameter("@compareLocation", new Point(-122.11758, 47.66901));
Cree un nuevo iterador mediante Container.GetItemQueryIterator<>
, el tipo genérico Result
y la variable query
. A continuación, use una combinación de un bucle while y foreach para recorrer en iteración todos los resultados en cada página de resultados. Genere cada resultado en la consola.
var distanceIterator = container.GetItemQueryIterator<Result>(query);
while (distanceIterator.HasMoreResults)
{
var response = await distanceIterator.ReadNextAsync();
foreach (var result in response)
{
Console.WriteLine($"[DISTANCE KM]\t{result}");
}
}
Nota
Para obtener más información sobre cómo enumerar los resultados de la consulta, consulte elementos de consulta.
Guarde el archivo Program.cs.
Vuelva a ejecutar la aplicación en un terminal mediante dotnet run
. Observe que la salida ahora incluye los resultados de la consulta.
dotnet run
[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 }
[DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
La funcionalidad LINQ a NoSQL del SDK de .NET admite la inclusión de tipos geoespaciales en las expresiones de consulta. Además, el SDK incluye métodos de extensión que se asignan a funciones integradas equivalentes:
Método de extensión | Función integrada |
---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Abra el archivo Program.cs.
Recupere el elemento Region
del contenedor con un identificador único de 1000
y almacénelo en una variable denominada region
.
Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
Use el método Container.GetItemLinqQueryable<>
para obtener una consulta LINQ y la compilación fluida de la consulta LINQ mediante la realización de estas tres acciones:
Use el método de extensión Queryable.Where<>
para filtrar solo los elementos con un category
equivalente a "business-office"
.
Use Queryable.Where<>
de nuevo para filtrar solo las ubicaciones dentro de la propiedad region
de la variable location
mediante Geometry.Within()
.
Traduzca la expresión LINQ a un iterador de fuente mediante CosmosLinqExtensions.ToFeedIterator<>
.
var regionIterator = container.GetItemLinqQueryable<Office>()
.Where(o => o.category == "business-office")
.Where(o => o.location.Within(region.location))
.ToFeedIterator<Office>();
Importante
En este ejemplo, la propiedad de ubicación de la oficina tiene un punto y la propiedad de ubicación de la región tiene un polígono. ST_WITHIN
determina si el punto de la oficina está dentro del polígono de la región.
A continuación, use una combinación de un bucle while y foreach para recorrer en iteración todos los resultados en cada página de resultados. Genere cada resultado en la consola.
while (regionIterator.HasMoreResults)
{
var response = await regionIterator.ReadNextAsync();
foreach (var office in response)
{
Console.WriteLine($"[IN REGION]\t{office}");
}
}
Guarde el archivo Program.cs.
Ejecute la aplicación una última vez en un terminal mediante dotnet run
. Observe que la salida ahora incluye los resultados de la segunda consulta basada en LINQ.
dotnet run
[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Quite la base de datos después de completar esta guía.
Abra un terminal y cree una variable de shell para el nombre de la cuenta y el grupo de recursos.
# Variable for resource group name
resourceGroupName="<name-of-your-resource-group>"
# Variable for account name
accountName="<name-of-your-account>"
Use az cosmosdb sql database delete
para eliminar la base de datos.
az cosmosdb sql database delete \
--resource-group "<resource-group-name>" \
--account-name "<nosql-account-name>" \
--name "cosmicworks"
Eventos
Compilación de Intelligent Apps
17 mar, 21 - 21 mar, 10
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Regístrese ahoraCursos
Módulo
Implementación de operaciones de punto de Azure Cosmos DB for NoSQL - Training
Escriba código para crear, leer, actualizar y eliminar elementos en Azure Cosmos DB for NoSQL.
Certificación
Microsoft Certified: Azure Cosmos DB Developer Specialty - Certifications
Escribe consultas eficaces, crea directivas de indexación, administra y aprovisiona recursos en la API de SQL y el SDK con Microsoft Azure Cosmos DB.
Documentación
Datos de ubicación geoespaciales y GeoJSON - Azure Cosmos DB for NoSQL
Cree objetos espaciales con Azure Cosmos DB para NoSQL, indéxelos y realice consultas con ellos.
ST_DISTANCE - Azure Cosmos DB for NoSQL
Una función del sistema de Azure Cosmos DB for NoSQL que devuelve la distancia entre dos puntos GeoJSON, Polygon, MultiPolygon o LineStrings.
Métricas de consulta SQL para Azure Cosmos DB for NoSQL
Aprenda cómo instrumentar y depurar el rendimiento de consultas SQL de las solicitudes de Azure Cosmos DB.