Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
VAN TOEPASSING OP: NoSQL
Met georuimtelijke gegevens in Azure Cosmos DB for NoSQL kunt u locatiegegevens opslaan en algemene query's uitvoeren, waaronder, maar niet beperkt tot:
- Zoeken of een locatie zich binnen een gedefinieerd gebied bevindt
- De afstand tussen twee locaties meten
- Bepalen of een pad doorkruist met een locatie of gebied
In deze handleiding wordt het proces voor het maken van georuimtelijke gegevens beschreven, het indexeren van de gegevens en het uitvoeren van query's op de gegevens in een container.
Vereisten
- Een bestaand Azure Cosmos DB for NoSQL-account.
- Als u geen Azure-abonnement hebt, kunt u Gratis Azure Cosmos DB voor NoSQL proberen.
- Als u een bestaand Azure-abonnement hebt, maakt u een nieuw Azure Cosmos DB for NoSQL-account.
- Nieuwste versie van .NET.
- Nieuwste versie van Azure CLI.
- Als u een lokale installatie gebruikt, meldt u zich aan bij de Azure CLI met behulp van de
az loginopdracht.
- Als u een lokale installatie gebruikt, meldt u zich aan bij de Azure CLI met behulp van de
Container- en indexeringsbeleid maken
Alle containers bevatten een standaardindexeringsbeleid dat georuimtelijke gegevens kan indexeren. Als u een aangepast indexeringsbeleid wilt maken, maakt u een account en geeft u een JSON-bestand op met de configuratie van het beleid. In deze sectie wordt een aangepaste ruimtelijke index gebruikt voor een zojuist gemaakte container.
Open een terminal.
Maak een shellvariabele voor de naam van uw Azure Cosmos DB for NoSQL-account en resourcegroep.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"Maak een nieuwe database met de naam
cosmicworksmet behulp vanaz cosmosdb sql database create.az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400Maak een nieuw JSON-bestand met de naam index-policy.json en voeg het volgende JSON-object toe aan het bestand.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }Hiermee
az cosmosdb sql container createmaakt u een nieuwe container met de naamlocationsmet een partitiesleutelpad van/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.jsonHaal ten slotte met behulp van
az cosmosdb showen een JMESPath-query het eindpunt voor uw account op.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"Noteer het accounteindpunt zoals u dit nodig hebt in de volgende sectie.
.NET SDK-consoletoepassing maken
De .NET SDK voor Azure Cosmos DB for NoSQL biedt klassen voor algemene GeoJSON-objecten. Gebruik deze SDK om het proces van het toevoegen van geografische objecten aan uw container te stroomlijnen.
Open een terminal in een lege map.
Maak een nieuwe .NET-toepassing met behulp van de
dotnet newopdracht met de consolesjabloon .dotnet new consoleImporteer het
Microsoft.Azure.CosmosNuGet-pakket met behulp van dedotnet add packageopdracht.dotnet add package Microsoft.Azure.Cosmos --version 3.*Waarschuwing
Entity Framework bevat momenteel geen ruimtelijke gegevens in Azure Cosmos DB voor NoSQL. Gebruik een van de Azure Cosmos DB for NoSQL SDK's voor sterk getypeerde GeoJSON-ondersteuning.
Importeer het
Azure.IdentityNuGet-pakket.dotnet add package Azure.Identity --version 1.*Bouw het project met de
dotnet buildopdracht.dotnet buildOpen de IDE (Integrated Developer Environment) van uw keuze in dezelfde map als uw .NET-consoletoepassing.
Open het zojuist gemaakte Program.cs-bestand en verwijder alle bestaande code. Voeg gebruiksrichtlijnen toe voor de
Microsoft.Azure.Cosmos,Microsoft.Azure.Cosmos.LinqenMicrosoft.Azure.Cosmos.Spatialnaamruimten.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;Voeg nog een using-instructie toe voor de
Azure.Identitynaamruimte.using Azure.Identity;Maak een nieuwe variabele met de naam
credentialvan het typeDefaultAzureCredential.DefaultAzureCredential credential = new();Maak een stringvariabele genaamd
endpointmet het eindpunt van uw Azure Cosmos DB for NoSQL-account.string endpoint = "<nosql-account-endpoint>";Maak een nieuw exemplaar van de
CosmosClientklasse doorconnectionStringmee te geven en verpakt het in een using-instructie.using CosmosClient client = new (connectionString);Haal een verwijzing op naar de eerder gemaakte container (
cosmicworks/locations) in het Azure Cosmos DB for NoSQL-account met behulp vanCosmosClient.GetDatabaseen vervolgensDatabase.GetContainer. Sla het resultaat op in een variabele met de naamcontainer.var container = client.GetDatabase("cosmicworks").GetContainer("locations");Sla bestand Program.cs op.
Georuimtelijke gegevens toevoegen
De .NET SDK bevat meerdere typen in de Microsoft.Azure.Cosmos.Spatial naamruimte die algemene GeoJSON-objecten vertegenwoordigen. Met deze typen wordt het proces voor het toevoegen van nieuwe locatiegegevens aan items in een container gestroomlijnd.
Maak een nieuw bestand met de naam Office.cs. Voeg in het bestand een using-instructie toe aan
Microsoft.Azure.Cosmos.Spatialen maak vervolgens eenOfficerecordtype met deze eigenschappen:Typen Beschrijving Standaardwaarde id stringUnieke identificatie name stringNaam van het kantoor location PointGeoJSON geografisch punt category stringPartitiesleutelwaarde business-officeusing Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );Notitie
Deze record bevat een
Pointeigenschap die een specifieke positie in GeoJSON vertegenwoordigt. Zie GeoJSON Point voor meer informatie.Maak nog een nieuw bestand met de naam Region.cs. Voeg nog een recordtype toe met de naam
Regionen met deze eigenschappen:Typen Beschrijving Standaardwaarde id stringUnieke identificatie name stringNaam van het kantoor location PolygonGeografische vorm van GeoJSON category stringPartitiesleutelwaarde business-regionusing Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );Notitie
Deze record bevat een
Polygoneigenschap die een shape vertegenwoordigt die bestaat uit lijnen die zijn getekend tussen meerdere locaties in GeoJSON. Zie GeoJSON Polygon voor meer informatie.Maak nog een nieuw bestand met de naam Result.cs. Voeg een recordtype toe genaamd
Resultmet deze twee eigenschappen:Typen Beschrijving name stringNaam van het overeenkomende resultaat distanceKilometers decimalAfstand in kilometers public record Result( string name, decimal distanceKilometers );Sla de bestanden Office.cs, Region.cs en Result.cs op.
Open het bestand Program.cs opnieuw.
Maak een nieuwe
Polygonin een variabele met de naammainCampusPolygon.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), }) } );Maak een nieuwe
Regionvariabele met de naammainCampusRegionmet behulp van de veelhoek, de unieke id1000en de naamMain Campus.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);Gebruik
Container.UpsertItemAsyncdit om de regio toe te voegen aan de container. Schrijf de gegevens van de regio naar de console.await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");Tip
In deze handleiding wordt upsert gebruikt in plaats van in te voegen , zodat u het script meerdere keren kunt uitvoeren zonder dat er een conflict tussen unieke id's ontstaat. Voor meer informatie over upsert-bewerkingen, zie items maken.
Maak een nieuwe
Pointvariabele met de naamheadquartersPoint. Gebruik deze variabele om een nieuweOfficevariabele te maken metheadquartersOfficebehulp van het punt, de unieke id0001en de naamHeadquarters.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);Maak een andere
Pointvariabele met de naamresearchPoint. Gebruik deze variabele om een andereOfficevariabele te maken metresearchOfficebehulp van het bijbehorende punt, de unieke id0002en de naamResearch and Development.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);Maak een
TransactionalBatchom beideOfficevariabelen als één transactie te upsert. Schrijf vervolgens de gegevens van beide kantoren naar de console.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}");Notitie
Zie transactionele batchbewerkingen voor meer informatie over transacties.
Sla bestand Program.cs op.
Voer de toepassing uit in een terminal met behulp van
dotnet run. U ziet dat de uitvoer van de toepassingsuitvoering informatie bevat over de drie nieuw gemaakte items.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 }
Georuimtelijke gegevens opvragen met noSQL-query
De typen in de Microsoft.Azure.Cosmos.Spatial naamruimte kunnen worden gebruikt als invoer voor een geparameteriseerde NoSQL-query om ingebouwde functies zoals ST_DISTANCE te gebruiken.
Open het Program.cs-bestand .
Maak een nieuwe
stringvariabele aan met de naamnosql. Deze query wordt in deze sectie gebruikt om de afstand tussen punten te meten.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 ";Tip
Met deze query wordt de georuimtelijke functie binnen een subquery opgeslagen om het proces van het hergebruik van de reeds berekende waarde meerdere keren in de
SELECTenWHEREcomponenten te vereenvoudigen.Maak een nieuwe
QueryDefinitionvariabele met de naamquerymet behulp van denosqlStringvariabele als parameter. Gebruik vervolgens deQueryDefinition.WithParameterfluent-methode meerdere keren om deze parameters toe te voegen aan de query:Waarde @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));Maak een nieuwe iterator met behulp van
Container.GetItemQueryIterator<>hetResultalgemene type en dequeryvariabele. Gebruik vervolgens een combinatie van een while-lus en foreach-lus om over alle resultaten op elke resultatenpagina te itereren. Voer elk resultaat uit naar de console.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}"); } }Notitie
Zie query-items voor meer informatie over het inventariseren van queryresultaten.
Sla bestand Program.cs op.
Voer de toepassing opnieuw uit in een terminal met behulp van
dotnet run. U ziet dat de uitvoer nu de resultaten van de query bevat.dotnet run[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
Georuimtelijke gegevens opvragen met LINQ
De LINQ-naar-NoSQL-functionaliteit in de .NET SDK biedt ondersteuning voor het opnemen van georuimtelijke typen in de queryexpressies. Verder bevat de SDK uitbreidingsmethoden die zijn toegewezen aan equivalente ingebouwde functies:
| Extensiemethode | Ingebouwde functie |
|---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Open het Program.cs-bestand .
Haal het
Regionitem op uit de container met een unieke id en1000sla het op in een variabele met de naamregion.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));Gebruik de
Container.GetItemLinqQueryable<>methode om een LINQ-query mogelijk te maken en de LINQ-query vloeiend te bouwen door deze drie acties uit te voeren:Gebruik de
Queryable.Where<>extensiemethode om te filteren op alleen items met eencategoryequivalent van"business-office".Gebruik
Queryable.Where<>opnieuw om te filteren op alleen locaties binnen de eigenschap vanregiondelocationvariabele met behulp vanGeometry.Within().Vertaal de LINQ-expressie naar een feed-iterator met behulp van
CosmosLinqExtensions.ToFeedIterator<>.
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();Belangrijk
In dit voorbeeld heeft de locatie-eigenschap van het kantoor een punt en heeft de locatie-eigenschap van de regio een veelhoek.
ST_WITHINbepaalt of het punt van het kantoor binnen de veelhoek van de regio valt.Gebruik een combinatie van een tijdje en foreach-lus om alle resultaten op elke pagina met resultaten te herhalen. Voer elk resultaat uit naar de console.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }Sla bestand Program.cs op.
Voer de toepassing een laatste keer uit in een terminal met behulp van
dotnet run. U ziet dat de uitvoer nu de resultaten van de tweede LINQ-query bevat.dotnet run[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Resources opschonen
Verwijder de database nadat u deze handleiding hebt voltooid.
Open een terminal en maak een shellvariabele voor de naam van uw account en resourcegroep.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"Gebruik
az cosmosdb sql database deletedeze optie om de database te verwijderen.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"