Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
PLATÍ PRO: NoSQL
Geoprostorová data ve službě Azure Cosmos DB for NoSQL umožňují ukládat informace o poloze a provádět běžné dotazy, včetně mimo jiné:
- Zjištění, jestli je umístění v definované oblasti
- Měření vzdálenosti mezi dvěma umístěními
- Stanovení, zda se cesta kříží s místem nebo oblastí
Tato příručka vás provede procesem vytváření geoprostorových dat, indexování dat a následného dotazování dat v kontejneru.
Požadavky
- Existující účet Azure Cosmos DB pro NoSQL.
- Pokud nemáte předplatné Azure, vyzkoušejte službu Azure Cosmos DB pro NoSQL zdarma.
- Pokud máte existující předplatné Azure, vytvořte nový účet Azure Cosmos DB for NoSQL.
- Nejnovější verze .NET
- Nejnovější verze Azure CLI
- Pokud používáte místní instalaci, přihlaste se k Azure CLI pomocí
az login
příkazu.
- Pokud používáte místní instalaci, přihlaste se k Azure CLI pomocí
Vytvoření zásad kontejneru a indexování
Všechny kontejnery obsahují výchozí zásady indexování, které úspěšně indexují geoprostorová data. Pokud chcete vytvořit vlastní zásady indexování, vytvořte účet a zadejte soubor JSON s konfigurací zásad. V této části se pro nově vytvořený kontejner používá vlastní prostorový index.
Otevřete terminál.
Vytvořte proměnnou shellu pro název vašeho účtu Azure Cosmos DB for NoSQL a skupiny prostředků.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Vytvořte novou databázi s názvem
cosmicworks
pomocíaz cosmosdb sql database create
.az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400
Vytvořte nový soubor JSON s názvem index-policy.json a do souboru přidejte následující objekt JSON.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }
Použijte
az cosmosdb sql container create
k vytvoření nového kontejneru s názvemlocations
s klíčem oddílu na cestě/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
Nakonec získejte koncový bod účtu pro váš účet pomocí
az cosmosdb show
a pomocí JMESPath dotazu.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"
Nahrajte koncový bod účtu, protože ho budete potřebovat v další části.
Vytvoření konzolové aplikace .NET SDK
Sada .NET SDK pro Azure Cosmos DB for NoSQL poskytuje třídy pro běžné objekty GeoJSON. Pomocí této sady SDK můžete zjednodušit proces přidávání geografických objektů do kontejneru.
Otevřete terminál v prázdném adresáři.
Pomocí příkazu se šablonou
dotnet new
vytvořte novou aplikaci .NET.dotnet new console
Importujte
Microsoft.Azure.Cosmos
balíček NuGet pomocídotnet add package
příkazu.dotnet add package Microsoft.Azure.Cosmos --version 3.*
Varování
Entity Framework v současné době prostorová data ve službě Azure Cosmos DB for NoSQL neobsahuje. Pro podporu GeoJSON silného typu použijte jednu ze sad SDK služby Azure Cosmos DB for NoSQL.
Importujte
Azure.Identity
balíček NuGet.dotnet add package Azure.Identity --version 1.*
Sestavte projekt pomocí
dotnet build
příkazu.dotnet build
Otevřete integrované vývojové prostředí (IDE) podle vašeho výběru ve stejném adresáři jako konzolová aplikace .NET.
Otevřete nově vytvořený soubor Program.cs a odstraňte veškerý existující kód. Přidejte direktivy using pro
Microsoft.Azure.Cosmos
obory názvů ,Microsoft.Azure.Cosmos.Linq
aMicrosoft.Azure.Cosmos.Spatial
obory názvů.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;
Přidejte další direktivu
Azure.Identity
using pro obor názvů.using Azure.Identity;
Vytvořte novou proměnnou s názvem
credential
typuDefaultAzureCredential
.DefaultAzureCredential credential = new();
Vytvořte řetězcovou proměnnou pojmenovanou
endpoint
z koncového bodu vašeho účtu Azure Cosmos DB for NoSQL.string endpoint = "<nosql-account-endpoint>";
Vytvořte novou instanci
CosmosClient
třídy, kteráconnectionString
předá a zabalí ji do příkazu using.using CosmosClient client = new (connectionString);
Načtěte odkaz na dříve vytvořený kontejner (
cosmicworks/locations
) v účtu Azure Cosmos DB for NoSQL pomocíCosmosClient.GetDatabase
a pakDatabase.GetContainer
. Uložte výsledek do proměnné s názvemcontainer
.var container = client.GetDatabase("cosmicworks").GetContainer("locations");
Uložte soubor Program.cs.
Přidání geoprostorových dat
Sada .NET SDK obsahuje více typů v Microsoft.Azure.Cosmos.Spatial
oboru názvů, které představují běžné objekty GeoJSON. Tyto typy zjednodušují proces přidávání nových informací o umístění do položek v kontejneru.
Vytvořte nový soubor s názvem Office.cs. Do souboru přidejte direktivu
Microsoft.Azure.Cosmos.Spatial
a poté vytvořteOffice
typ záznamu s těmito vlastnostmi:Typ Popis Výchozí hodnota id string
Jedinečný identifikátor Jméno string
Název kanceláře location Point
Geografický bod GeoJSON kategorie string
Hodnota klíče oddílu business-office
using Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );
Poznámka:
Tento záznam obsahuje
Point
vlastnost představující konkrétní pozici v GeoJSON. Další informace naleznete v tématu GeoJSON Point.Vytvořte další nový soubor s názvem Region.cs. Přidejte další typ záznamu s názvem
Region
s těmito vlastnostmi:Typ Popis Výchozí hodnota id string
Jedinečný identifikátor Jméno string
Název kanceláře location Polygon
Geografický tvar GeoJSON kategorie string
Hodnota klíče oddílu business-region
using Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );
Poznámka:
Tento záznam obsahuje
Polygon
vlastnost představující obrazec složený z čar nakreslených mezi několika umístěními v GeoJSON. Další informace naleznete v tématu GeoJSON Polygon.Vytvořte další nový soubor s názvem Result.cs. Přidejte typ záznamu pojmenovaný
Result
s těmito dvěma vlastnostmi:Typ Popis Jméno string
Název odpovídajícího výsledku vzdálenostKilometry decimal
Vzdálenost v kilometrech public record Result( string name, decimal distanceKilometers );
Uložte soubory Office.cs, Region.cs a Result.cs.
Znovu otevřete soubor Program.cs.
Vytvořte nový
Polygon
v proměnné s názvemmainCampusPolygon
.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), }) } );
Vytvořte novou
Region
proměnnou s názvemmainCampusRegion
pomocí mnohoúhelníku, jedinečného identifikátoru1000
a názvuMain Campus
.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
Slouží
Container.UpsertItemAsync
k přidání oblasti do kontejneru. Napište informace o oblasti do konzoly.await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");
Tip
Tato příručka používá upsert místo vložení, takže skript můžete spustit vícekrát, aniž by došlo ke konfliktu mezi jedinečnými identifikátory. Další informace o operacích typu upsert najdete v tématu vytváření položek.
Vytvořte novou
Point
proměnnou s názvemheadquartersPoint
. Pomocí této proměnné vytvořte novouOffice
proměnnou s názvemheadquartersOffice
pomocí bodu, jedinečného identifikátoru0001
a názvuHeadquarters
.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
Vytvořte další
Point
proměnnou s názvemresearchPoint
. Pomocí této proměnné vytvořte jinouOffice
proměnnou s názvemresearchOffice
pomocí odpovídajícího bodu, jedinečného identifikátoru0002
a názvuResearch and Development
.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);
Vytvořte
TransactionalBatch
, který provede vložení nebo aktualizaci obou proměnnýchOffice
v rámci jedné transakce. Pak na konzolu napište informace o obou kancelářích.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}");
Poznámka:
Další informace o transakcích naleznete v tématu transakční dávkové operace.
Uložte soubor Program.cs.
Spusťte aplikaci v terminálu pomocí
dotnet run
příkazu . Všimněte si, že výstup spuštění aplikace obsahuje informace o třech nově vytvořených položkách.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 }
Dotazování geoprostorových dat pomocí dotazu NoSQL
Typy v Microsoft.Azure.Cosmos.Spatial
oboru názvů lze použít jako vstupy do parametrizovaného dotazu NoSQL pro použití předdefinovaných funkcí, jako je ST_DISTANCE
.
Otevřete soubor Program.cs.
Vytvořte novou
string
proměnnou s názvemnosql
, která se v této části používá k měření vzdálenosti mezi body.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 ";
Vytvořte novou
QueryDefinition
proměnnou s názvemquery
pomocínosqlString
proměnné jako parametru. K přidání těchto parametrů do dotazu pak použijte fluent metoduQueryDefinition.WithParameter
vícekrát:Hodnota @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));
Vytvořte nový iterátor pomocí
Container.GetItemQueryIterator<>
Result
obecného typu aquery
proměnné. Potom použijte kombinaci smyčky while a foreach k iteraci přes všechny výsledky na každé stránce. Vypíše každý výsledek do konzoly.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}"); } }
Poznámka:
Další informace o vytvoření výčtu výsledků dotazu najdete v tématu položky dotazu.
Uložte soubor Program.cs.
Spusťte aplikaci znovu v terminálu pomocí
dotnet run
příkazu . Všimněte si, že výstup teď obsahuje výsledky dotazu.dotnet run
[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
Dotazování geoprostorových dat pomocí LINQ
Funkce LINQ to NoSQL v sadě .NET SDK podporuje zahrnutí geoprostorových typů do výrazů dotazu. Navíc sada SDK obsahuje rozšiřující metody, které se mapují na ekvivalentní předdefinované funkce.
Metoda rozšíření | Integrovaná funkce |
---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Otevřete soubor Program.cs.
Region
Načtěte položku z kontejneru s jedinečným identifikátorem1000
a uložte ji do proměnné s názvemregion
.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
Použijte metodu
Container.GetItemLinqQueryable<>
k získání objektu, na kterém lze provádět dotazy LINQ, a plynule sestavte dotaz LINQ provedením těchto tří akcí:Použijte metodu
Queryable.Where<>
rozšíření k filtrování pouze položek s ekvivalentemcategory
"business-office"
.Opět použijte
Queryable.Where<>
k filtrování pouze těch umístění, které jsou v rámci vlastnostilocation
proměnnéregion
, pomocíGeometry.Within()
.Přeložte výraz LINQ na iterátor informačního kanálu pomocí
CosmosLinqExtensions.ToFeedIterator<>
.
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();
Důležité
V tomto příkladu má vlastnost polohy kanceláře bod a vlastnost polohy oblasti má mnohoúhelník.
ST_WITHIN
určuje, zda je bod kanceláře v polygonu oblasti.Pomocí kombinace smyčky while a foreach iterujte přes všechny výsledky na každé stránce výsledků. Vypíše každý výsledek do konzoly.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }
Uložte soubor Program.cs.
Spusťte aplikaci jednou naposledy v terminálu pomocí
dotnet run
příkazu . Všimněte si, že výstup teď obsahuje výsledky druhého dotazu založeného na LINQ.dotnet run
[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Vyčištění prostředků
Po dokončení této příručky odeberte databázi.
Otevřete terminál a vytvořte shell proměnnou pro jméno vašeho účtu a skupiny prostředků.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Slouží
az cosmosdb sql database delete
k odebrání databáze.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"