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 loginpří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
cosmicworkspomocíaz cosmosdb sql database create.az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400Vytvoř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 createk vytvoření nového kontejneru s názvemlocationss 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.jsonNakonec získejte koncový bod účtu pro váš účet pomocí
az cosmosdb showa 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 newvytvořte novou aplikaci .NET.dotnet new consoleImportujte
Microsoft.Azure.Cosmosbalíček NuGet pomocídotnet add packagepří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.Identitybalíček NuGet.dotnet add package Azure.Identity --version 1.*Sestavte projekt pomocí
dotnet buildpříkazu.dotnet buildOtevř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.Cosmosobory názvů ,Microsoft.Azure.Cosmos.LinqaMicrosoft.Azure.Cosmos.Spatialobory názvů.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;Přidejte další direktivu
Azure.Identityusing pro obor názvů.using Azure.Identity;Vytvořte novou proměnnou s názvem
credentialtypuDefaultAzureCredential.DefaultAzureCredential credential = new();Vytvořte řetězcovou proměnnou pojmenovanou
endpointz koncového bodu vašeho účtu Azure Cosmos DB for NoSQL.string endpoint = "<nosql-account-endpoint>";Vytvořte novou instanci
CosmosClienttřídy, kteráconnectionStringpř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.GetDatabasea 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.Spatiala poté vytvořteOfficetyp záznamu s těmito vlastnostmi:Typ Popis Výchozí hodnota id stringJedinečný identifikátor Jméno stringNázev kanceláře location PointGeografický bod GeoJSON kategorie stringHodnota klíče oddílu business-officeusing Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );Poznámka:
Tento záznam obsahuje
Pointvlastnost 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
Regions těmito vlastnostmi:Typ Popis Výchozí hodnota id stringJedinečný identifikátor Jméno stringNázev kanceláře location PolygonGeografický tvar GeoJSON kategorie stringHodnota klíče oddílu business-regionusing Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );Poznámka:
Tento záznam obsahuje
Polygonvlastnost 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ý
Results těmito dvěma vlastnostmi:Typ Popis Jméno stringNázev odpovídajícího výsledku vzdálenostKilometry decimalVzdá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ý
Polygonv 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
Regionproměnnou s názvemmainCampusRegionpomocí mnohoúhelníku, jedinečného identifikátoru1000a názvuMain Campus.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);Slouží
Container.UpsertItemAsynck 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
Pointproměnnou s názvemheadquartersPoint. Pomocí této proměnné vytvořte novouOfficeproměnnou s názvemheadquartersOfficepomocí bodu, jedinečného identifikátoru0001a názvuHeadquarters.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);Vytvořte další
Pointproměnnou s názvemresearchPoint. Pomocí této proměnné vytvořte jinouOfficeproměnnou s názvemresearchOfficepomocí odpovídajícího bodu, jedinečného identifikátoru0002a 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ýchOfficev 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 runpří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
stringpromě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
QueryDefinitionproměnnou s názvemquerypomocínosqlStringproměnné jako parametru. K přidání těchto parametrů do dotazu pak použijte fluent metoduQueryDefinition.WithParameterví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<>Resultobecného typu aquerypromě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 runpří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.
RegionNačtěte položku z kontejneru s jedinečným identifikátorem1000a 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 vlastnostiregionproměnnélocation, 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_WITHINurč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 runpří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 deletek odebrání databáze.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"