Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
DOTYCZY: NoSQL
Dane geoprzestrzenne w usłudze Azure Cosmos DB for NoSQL umożliwiają przechowywanie informacji o lokalizacji i wykonywanie typowych zapytań, w tym między innymi:
- Znajdowanie, czy lokalizacja znajduje się w zdefiniowanym obszarze
- Mierzenie odległości między dwiema lokalizacjami
- Określanie, czy ścieżka przecina się z lokalizacją lub obszarem
W tym przewodniku przedstawiono proces tworzenia danych geoprzestrzennych, indeksowania danych, a następnie wykonywania zapytań dotyczących danych w kontenerze.
Wymagania wstępne
- Istniejące konto usługi Azure Cosmos DB for NoSQL.
- Jeśli nie masz subskrypcji platformy Azure, wypróbuj bezpłatnie usługę Azure Cosmos DB dla noSQL.
- Jeśli masz istniejącą subskrypcję platformy Azure, utwórz nowe konto usługi Azure Cosmos DB for NoSQL.
- Najnowsza wersja platformy .NET.
- Najnowsza wersja interfejsu wiersza polecenia platformy Azure.
- Jeśli używasz instalacji lokalnej, zaloguj się do interfejsu
az loginwiersza polecenia platformy Azure przy użyciu polecenia .
- Jeśli używasz instalacji lokalnej, zaloguj się do interfejsu
Tworzenie zasad kontenera i indeksowania
Wszystkie kontenery zawierają domyślne zasady indeksowania, które pomyślnie indeksują dane geoprzestrzenne. Aby utworzyć dostosowane zasady indeksowania, utwórz konto i określ plik JSON z konfiguracją zasad. W tej sekcji niestandardowy indeks przestrzenny jest używany dla nowo utworzonego kontenera.
Otwórz terminal.
Utwórz zmienną powłoki dla nazwy konta i grupy zasobów usługi 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>"Utwórz nową bazę danych o nazwie
cosmicworksprzy użyciu poleceniaaz cosmosdb sql database create.az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400Utwórz nowy plik JSON o nazwie index-policy.json i dodaj następujący obiekt JSON do pliku.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }Użyj
az cosmosdb sql container createpolecenia , aby utworzyć nowy kontener o nazwielocationsz ścieżką/regionklucza partycji .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.jsonNa koniec pobierz punkt końcowy konta dla konta przy użyciu polecenia
az cosmosdb showi zapytanie JMESPath.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"Zarejestruj punkt końcowy konta, ponieważ będzie to potrzebne w następnej sekcji.
Tworzenie aplikacji konsolowej zestawu SDK platformy .NET
Zestaw .NET SDK dla usługi Azure Cosmos DB for NoSQL udostępnia klasy dla typowych obiektów GeoJSON. Użyj tego zestawu SDK, aby usprawnić proces dodawania obiektów geograficznych do kontenera.
Otwórz terminal w pustym katalogu.
Utwórz nową aplikację .NET przy użyciu
dotnet newpolecenia z szablonem konsoli .dotnet new consoleZaimportuj
Microsoft.Azure.Cosmosdotnet add packagepakiet NuGet przy użyciu polecenia .dotnet add package Microsoft.Azure.Cosmos --version 3.*Ostrzeżenie
Program Entity Framework nie obsługuje obecnie danych przestrzennych w usłudze Azure Cosmos DB for NoSQL. Użyj jednego z zestawów SDK usługi Azure Cosmos DB for NoSQL w celu obsługi silnie typizowanego pliku GeoJSON.
Zaimportuj
Azure.Identitypakiet NuGet.dotnet add package Azure.Identity --version 1.*Skompiluj projekt za
dotnet buildpomocą polecenia .dotnet buildOtwórz wybrane zintegrowane środowisko deweloperskie (IDE) w tym samym katalogu co aplikacja konsolowa platformy .NET.
Otwórz nowo utworzony plik Program.cs i usuń dowolny istniejący kod. Dodaj dyrektywy using dla
Microsoft.Azure.Cosmosprzestrzeni nazw ,Microsoft.Azure.Cosmos.LinqiMicrosoft.Azure.Cosmos.Spatial.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;Dodaj kolejną dyrektywę
Azure.Identityusing dla przestrzeni nazw.using Azure.Identity;Utwórz nową zmienną o nazwie
credentialtypuDefaultAzureCredential.DefaultAzureCredential credential = new();Utwórz zmienną ciągu o nazwie
endpointprzy użyciu punktu końcowego konta usługi Azure Cosmos DB for NoSQL.string endpoint = "<nosql-account-endpoint>";Utwórz nowe wystąpienie klasy przekazującej
CosmosClientconnectionStringi zawijając je w instrukcji using.using CosmosClient client = new (connectionString);Pobierz odwołanie do wcześniej utworzonego kontenera (
cosmicworks/locations) na koncie usługi Azure Cosmos DB for NoSQL przy użyciu poleceniaCosmosClient.GetDatabase, a następnieDatabase.GetContainer. Zapisz wynik w zmiennej o nazwiecontainer.var container = client.GetDatabase("cosmicworks").GetContainer("locations");Zapisz plik Program.cs.
Dodawanie danych geoprzestrzennych
Zestaw .NET SDK zawiera wiele typów w Microsoft.Azure.Cosmos.Spatial przestrzeni nazw do reprezentowania typowych obiektów GeoJSON. Te typy usprawniają proces dodawania nowych informacji o lokalizacji do elementów w kontenerze.
Utwórz nowy plik o nazwie Office.cs. W pliku dodaj dyrektywę using, a
Microsoft.Azure.Cosmos.Spatialnastępnie utwórz typ rekorduOfficez następującymi właściwościami:Typ Opis Domyślna wartość id stringUnikatowy identyfikator name stringNazwa biura location PointPunkt geograficzny GeoJSON kategoria stringWartość klucza partycji business-officeusing Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );Uwaga
Ten rekord zawiera właściwość reprezentującą
Pointokreśloną pozycję w formacie GeoJSON. Aby uzyskać więcej informacji, zobacz GeoJSON Point (Punkt GeoJSON).Utwórz kolejny nowy plik o nazwie Region.cs. Dodaj inny typ rekordu o nazwie z
Regionnastępującymi właściwościami:Typ Opis Domyślna wartość id stringUnikatowy identyfikator name stringNazwa biura location PolygonKształt geograficzny w formacie GeoJSON kategoria stringWartość klucza partycji business-regionusing Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );Uwaga
Ten rekord zawiera właściwość reprezentującą
Polygonkształt składający się z linii rysowanych między wieloma lokalizacjami w formacie GeoJSON. Aby uzyskać więcej informacji, zobacz GeoJSON Polygon.Utwórz kolejny nowy plik o nazwie Result.cs. Dodaj typ rekordu o nazwie o
Resultnastępujących dwóch właściwościach:Typ Opis name stringNazwa dopasowanego wyniku distanceKilometers decimalOdległość w kilometrach public record Result( string name, decimal distanceKilometers );Zapisz pliki Office.cs, Region.cs i Result.cs.
Otwórz ponownie plik Program.cs.
Utwórz nową
Polygonw zmiennej o nazwiemainCampusPolygon.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), }) } );Utwórz nową
Regionzmienną o nazwiemainCampusRegionprzy użyciu wielokąta, unikatowego identyfikatora1000i nazwyMain Campus.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);Użyj
Container.UpsertItemAsyncpolecenia , aby dodać region do kontenera. Zapisz informacje o regionie w konsoli programu .await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");Napiwek
W tym przewodniku użyto operacji upsert zamiast wstawiania, aby można było uruchomić skrypt wielokrotnie bez powodowania konfliktu między unikatowymi identyfikatorami. Aby uzyskać więcej informacji na temat operacji upsert, zobacz tworzenie elementów.
Utwórz nową
Pointzmienną o nazwieheadquartersPoint. Użyj tej zmiennej, aby utworzyć nowąOfficezmienną o nazwieheadquartersOfficeprzy użyciu punktu, unikatowego identyfikatora0001i nazwyHeadquarters.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);Utwórz inną zmienną
Pointo nazwieresearchPoint. Użyj tej zmiennej, aby utworzyć innąOfficezmienną o nazwieresearchOfficeprzy użyciu odpowiedniego punktu, unikatowego identyfikatora0002i nazwyResearch and Development.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);Utwórz wartość ,
TransactionalBatchaby upsert obieOfficezmienne jako pojedyncza transakcja. Następnie zapisz informacje o obu biurach w konsoli programu .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}");Uwaga
Aby uzyskać więcej informacji na temat transakcji, zobacz operacje transakcyjne wsadowe.
Zapisz plik Program.cs.
Uruchom aplikację w terminalu przy użyciu polecenia
dotnet run. Zwróć uwagę, że dane wyjściowe przebiegu aplikacji zawierają informacje o trzech nowo utworzonych elementach.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 }
Wykonywanie zapytań dotyczących danych geoprzestrzennych przy użyciu zapytania NoSQL
Typy w Microsoft.Azure.Cosmos.Spatial przestrzeni nazw mogą służyć jako dane wejściowe do zapytania sparametryzowanego NoSQL w celu używania wbudowanych funkcji, takich jak ST_DISTANCE.
Otwórz plik Program.cs.
Utwórz nową
stringzmienną o nazwienosqlz zapytaniem, która jest używana w tej sekcji do mierzenia odległości między punktami.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 ";Utwórz nową
QueryDefinitionzmienną o nazwiequeryprzy użyciu zmiennejnosqlStringjako parametru. Następnie użyjQueryDefinition.WithParametermetody fluent wiele razy, aby dodać te parametry do zapytania:Wartość @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));Utwórz nowy iterator przy użyciu
Container.GetItemQueryIterator<>typuResultogólnego i zmiennejquery. Następnie użyj kombinacji pętli while i foreach, aby iterować wszystkie wyniki na każdej stronie wyników. Wyprowadź każdy wynik do konsoli.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}"); } }Uwaga
Aby uzyskać więcej informacji na temat wyliczania wyników zapytania, zobacz elementy zapytania.
Zapisz plik Program.cs.
Uruchom ponownie aplikację w terminalu przy użyciu polecenia
dotnet run. Zwróć uwagę, że dane wyjściowe zawierają teraz wyniki zapytania.dotnet run[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
Wykonywanie zapytań dotyczących danych geoprzestrzennych przy użyciu LINQ
Funkcje LINQ to NoSQL w zestawie SDK platformy .NET obsługują uwzględnienie typów geoprzestrzennych w wyrażeniach zapytań. Ponadto zestaw SDK zawiera metody rozszerzeń mapowane na równoważne wbudowane funkcje:
| Metoda rozszerzenia | Wbudowana funkcja |
|---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Otwórz plik Program.cs.
RegionPobierz element z kontenera z unikatowym identyfikatorem1000i zapisz go w zmiennej o nazwieregion.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));Container.GetItemLinqQueryable<>Użyj metody , aby uzyskać zapytanie LINQ i skompiluj zapytanie LINQ płynnie, wykonując następujące trzy akcje:Queryable.Where<>Użyj metody rozszerzenia, aby filtrować tylko elementy o odpowiednikucategory"business-office".Użyj
Queryable.Where<>ponownie, aby filtrować tylko do lokalizacji we właściwości zmiennejregionlocationprzy użyciu poleceniaGeometry.Within().Przetłumacz wyrażenie LINQ na iterator kanału informacyjnego przy użyciu polecenia
CosmosLinqExtensions.ToFeedIterator<>.
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();Ważne
W tym przykładzie właściwość lokalizacji biura ma punkt, a właściwość lokalizacji regionu ma wielokąt.
ST_WITHINOkreśla, czy punkt biura znajduje się w obrębie wielokąta regionu.Użyj kombinacji pętli while i foreach, aby iterować wszystkie wyniki na każdej stronie wyników. Wyprowadź każdy wynik do konsoli.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }Zapisz plik Program.cs.
Uruchom aplikację po raz ostatni w terminalu przy użyciu polecenia
dotnet run. Zwróć uwagę, że dane wyjściowe zawierają teraz wyniki drugiego zapytania opartego na linQ.dotnet run[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Czyszczenie zasobów
Po ukończeniu tego przewodnika usuń bazę danych.
Otwórz terminal i utwórz zmienną powłoki dla nazwy konta i grupy zasobów.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"Użyj polecenia
az cosmosdb sql database delete, aby usunąć bazę danych.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"