GeoJSON-helyadatok indexelése és lekérdezése a NoSQL-hez készült Azure Cosmos DB-ben
A KÖVETKEZŐRE VONATKOZIK: NoSQL
Az Azure Cosmos DB for NoSQL térinformatikai adatai lehetővé teszik a helyadatok tárolását és a gyakori lekérdezések végrehajtását, többek között a következőkre:
- Annak megállapítása, hogy egy hely egy meghatározott területen belül van-e
- Két hely távolságának mérése
- Annak meghatározása, hogy egy elérési út keresztez-e egy helyet vagy területet
Ez az útmutató végigvezeti a térinformatikai adatok létrehozásának, az adatok indexelésének, majd a tárolóban lévő adatok lekérdezésének folyamatán.
Előfeltételek
- Egy meglévő Azure Cosmos DB for NoSQL-fiók.
- Ha nem rendelkezik Azure-előfizetéssel, ingyenesen kipróbálhatja az Azure Cosmos DB for NoSQL-t.
- Ha már rendelkezik Azure-előfizetéssel, hozzon létre egy új Azure Cosmos DB for NoSQL-fiókot.
- A .NET legújabb verziója.
- Az Azure CLI legújabb verziója.
- Ha helyi telepítést használ, jelentkezzen be az Azure CLI-be a
az login
parancs használatával.
- Ha helyi telepítést használ, jelentkezzen be az Azure CLI-be a
Tároló- és indexelési szabályzat létrehozása
Minden tároló tartalmaz egy alapértelmezett indexelési szabályzatot, amely sikeresen indexeli a térinformatikai adatokat. Testreszabott indexelési szabályzat létrehozásához hozzon létre egy fiókot, és adjon meg egy JSON-fájlt a szabályzat konfigurációjával. Ebben a szakaszban egy egyéni térbeli indexet használunk egy újonnan létrehozott tárolóhoz.
Nyisson meg egy terminált.
Hozzon létre egy rendszerhéjváltozót az Azure Cosmos DB for NoSQL-fiók és erőforráscsoport nevéhez.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Hozzon létre egy új, a következővel elnevezett adatbázist
cosmicworks
az cosmosdb sql database create
: .az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400
Hozzon létre egy index-policy.json nevű új JSON-fájlt, és adja hozzá a következő JSON-objektumot a fájlhoz.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }
A következő partíciókulcs elérési útjával
/region
elnevezettlocations
új tároló létrehozásához használhatóaz cosmosdb sql container create
.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
Végül szerezze be a fiók végpontját egy JMESPath-lekérdezéssel
az cosmosdb show
.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"
Jegyezze fel a fiókvégpontot, ahogy a következő szakaszban szüksége lesz rá.
.NET SDK-konzolalkalmazás létrehozása
Az Azure Cosmos DB for NoSQL .NET SDK osztályokat biztosít a gyakori GeoJSON-objektumokhoz. Ezzel az SDK-val egyszerűsítheti a földrajzi objektumok tárolóhoz való hozzáadásának folyamatát.
Nyisson meg egy terminált egy üres könyvtárban.
Hozzon létre egy új .NET-alkalmazást a
dotnet new
konzolsablon parancsával.dotnet new console
Importálja a
Microsoft.Azure.Cosmos
NuGet-csomagot adotnet add package
paranccsal.dotnet add package Microsoft.Azure.Cosmos --version 3.*
Figyelmeztetés
Az Entity Framework jelenleg nem végez térbeli adatokat a NoSQL-hez készült Azure Cosmos DB-ben. Használja az Egyik Azure Cosmos DB for NoSQL SDK-t az erős típusú GeoJSON-támogatáshoz.
Importálja a
Azure.Identity
NuGet-csomagot.dotnet add package Azure.Identity --version 1.*
Hozza létre a projektet a
dotnet build
paranccsal.dotnet build
Nyissa meg a választott integrált fejlesztői környezetet (IDE) ugyanabban a könyvtárban, mint a .NET-konzolalkalmazás.
Nyissa meg az újonnan létrehozott Program.cs fájlt, és törölje a meglévő kódot. Adjon hozzá a ,
Microsoft.Azure.Cosmos.Linq
, ésMicrosoft.Azure.Cosmos.Spatial
névterekre vonatkozóMicrosoft.Azure.Cosmos
direktívákat.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;
Adjon hozzá egy másik, a névtérhez tartozó direktívát
Azure.Identity
.using Azure.Identity;
Hozzon létre egy új, típusnak
DefaultAzureCredential
nevezettcredential
változót.DefaultAzureCredential credential = new();
Hozzon létre egy sztringváltozót az Azure Cosmos DB for NoSQL-fiókvégponttal.
endpoint
string endpoint = "<nosql-account-endpoint>";
Hozzon létre egy új példányt az
CosmosClient
átadó osztálybólconnectionString
, és csomagolja egy használatba vételi utasításba.using CosmosClient client = new (connectionString);
Kérjen le egy hivatkozást a korábban létrehozott tárolóra (
cosmicworks/locations
) az Azure Cosmos DB for NoSQL-fiókban a használatávalCosmosClient.GetDatabase
, majd a használatávalDatabase.GetContainer
. Tárolja az eredményt egy névvel ellátottcontainer
változóban.var container = client.GetDatabase("cosmicworks").GetContainer("locations");
Mentse a Program.cs fájlt.
Térinformatikai adatok hozzáadása
A .NET SDK több típust is tartalmaz a névtérben a Microsoft.Azure.Cosmos.Spatial
gyakori GeoJSON-objektumok megjelenítéséhez. Ezek a típusok leegyszerűsítik az új helyinformációk tárolóban lévő elemekhez való hozzáadásának folyamatát.
Hozzon létre egy Office.cs nevű új fájlt. A fájlban adjon hozzá egy használati utasítást
Microsoft.Azure.Cosmos.Spatial
, majd hozzon létre egy rekordtípustOffice
az alábbi tulajdonságokkal:Típus Leírás Alapértelmezett érték id string
Egyedi azonosító név string
Az iroda neve hely Point
GeoJSON földrajzi pont kategória string
Partíciókulcs értéke business-office
using Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );
Feljegyzés
Ez a rekord tartalmaz egy tulajdonságot
Point
, amely a GeoJSON adott pozícióját jelöli. További információ: GeoJSON Point.Hozzon létre egy Region.cs nevű új fájlt. Adjon hozzá egy másik rekordtípust a következő tulajdonságokkal:
Region
Típus Leírás Alapértelmezett érték id string
Egyedi azonosító név string
Az iroda neve hely Polygon
GeoJSON földrajzi alakzat kategória string
Partíciókulcs értéke business-region
using Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );
Feljegyzés
Ez a rekord egy olyan tulajdonságot
Polygon
tartalmaz, amely a GeoJSON több helye között rajzolt vonalakból álló alakzatot jelöl. További információ: GeoJSON Polygon.Hozzon létre egy másik, Result.cs nevű új fájlt. Adjon hozzá egy rekordtípust
Result
a következő két tulajdonsággal:Típus Leírás név string
Az egyező eredmény neve distanceKilometers decimal
Távolság kilométerben public record Result( string name, decimal distanceKilometers );
Mentse a Office.cs, Region.cs és Result.cs fájlokat.
Nyissa meg újra a Program.cs fájlt.
Hozzon létre egy újat
Polygon
egy nevűmainCampusPolygon
változóban.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), }) } );
Hozzon létre egy új
Region
változótmainCampusRegion
a sokszög, az egyedi azonosító1000
és a névMain Campus
használatával.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
A régió a tárolóhoz való hozzáadásához használható
Container.UpsertItemAsync
. Írja be a régió adatait a konzolra.await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");
Hozzon létre egy új
Point
, elnevezett változótheadquartersPoint
. Ezzel a változóval hozzon létre egy újOffice
változótheadquartersOffice
a pont, az egyedi azonosító0001
és a névHeadquarters
használatával.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
Hozzon létre egy másik
Point
, elnevezett változótresearchPoint
. Ezzel a változóval hozzon létre egy másikOffice
, a megfelelő pont, az egyedi azonosító0002
és a névResearch and Development
használatával elnevezettresearchOffice
változót.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);
Hozzon létre egy
TransactionalBatch
to-upsert mindkétOffice
változót egyetlen tranzakcióként. Ezután írja be mindkét office-információt a konzolra.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}");
Feljegyzés
A tranzakciókról további információt a tranzakciós kötegműveletekben talál.
Mentse a Program.cs fájlt.
Futtassa az alkalmazást egy terminálban a következő használatával
dotnet run
: . Figyelje meg, hogy az alkalmazásfuttatás kimenete tartalmazza a három újonnan létrehozott elem adatait.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 }
Térinformatikai adatok lekérdezése NoSQL-lekérdezéssel
A névtérben lévő Microsoft.Azure.Cosmos.Spatial
típusok egy NoSQL paraméteres lekérdezés bemeneteként használhatók az olyan beépített függvények használatához, mint a ST_DISTANCE
.
Nyissa meg a Program.cs fájlt.
Hozzon létre egy új
string
, a lekérdezéssel elnevezettnosql
változót ebben a szakaszban a pontok közötti távolság mérésére.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 ";
Tipp.
Ez a lekérdezés egy al lekérdezésbe helyezi a térinformatikai függvényt, hogy leegyszerűsítse a már kiszámított érték többszöri újrafelhasználását a záradékokban és
WHERE
aSELECT
záradékokban.Hozzon létre egy új
QueryDefinition
változót,query
amely paraméterként használja anosqlString
változót. Ezután aQueryDefinition.WithParameter
fluent metódus többszöri használatával adja hozzá ezeket a paramétereket a lekérdezéshez:Érték @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));
Hozzon létre egy új iterátort az
Result
általános típus és aquery
változó használatávalContainer.GetItemQueryIterator<>
. Ezután használjon egy kis idő kombinációját, és foreach hurok használatával iterálja át az összes találatot az egyes találatoldalakon. Kimenet minden eredményt a konzolon.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}"); } }
Feljegyzés
A lekérdezési eredmények számbavételéről további információt a lekérdezéselemekben talál.
Mentse a Program.cs fájlt.
Futtassa újra az alkalmazást egy terminálban a következő használatával
dotnet run
: . Figyelje meg, hogy a kimenet most már tartalmazza a lekérdezés eredményeit.dotnet run
[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
Térinformatikai adatok lekérdezése a LINQ használatával
A .NET SDK LINQ–NoSQL funkciója támogatja a térinformatikai típusokat a lekérdezési kifejezésekben. Az SDK emellett olyan bővítménymetelyeket is tartalmaz, amelyek egyenértékű beépített függvényekhez lesznek megfeleltetve:
Bővítménymetódus | Beépített függvény |
---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Nyissa meg a Program.cs fájlt.
Kérje le az
Region
elemet a tárolóból egyedi azonosítóval1000
, és tárolja azt egy nevesítettregion
változóban.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
Container.GetItemLinqQueryable<>
A módszer használatával lekérdezhető a LINQ, és a LINQ-lekérdezést az alábbi három művelet végrehajtásával hozhatja létre folyékonyan:A bővítménymetódussal csak azokkal
Queryable.Where<>
egyenértékű elemekrecategory
szűrhet"business-office"
.A szűrő ismételt használatával
Queryable.Where<>
csak a változó tulajdonságánlocation
belüli helyekre szűrhet aregion
használatávalGeometry.Within()
.A LINQ kifejezés lefordítása hírcsatorna-iterátorra a következő használatával
CosmosLinqExtensions.ToFeedIterator<>
: .
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();
Fontos
Ebben a példában az iroda helytulajdonságának van egy pontja, a régió helytulajdonságának pedig sokszöge.
ST_WITHIN
meghatározza, hogy a hivatali pont a régió sokszögén belül van-e.Használjon egy kis idő kombinációját, és foreach hurok segítségével iterálja át az összes találatot az egyes találatoldalakon. Kimenet minden eredményt a konzolon.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }
Mentse a Program.cs fájlt.
Futtassa utoljára az alkalmazást egy terminálban a következő használatával
dotnet run
: . Figyelje meg, hogy a kimenet most már tartalmazza a második LINQ-alapú lekérdezés eredményeit.dotnet run
[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Az erőforrások eltávolítása
Az útmutató elvégzése után távolítsa el az adatbázist.
Nyisson meg egy terminált, és hozzon létre egy rendszerhéjváltozót a fiók és az erőforráscsoport nevéhez.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Az adatbázis eltávolítására használható
az cosmosdb sql database delete
.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"