Megosztás a következőn keresztül:


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

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.

  1. Nyisson meg egy terminált.

  2. 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>"
    
  3. 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
    
  4. 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"
          ]
        }
      ]
    }
    
  5. A következő partíciókulcs elérési útjával /regionelnevezett locations ú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
    
  6. 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"
    
  7. 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.

  1. Nyisson meg egy terminált egy üres könyvtárban.

  2. Hozzon létre egy új .NET-alkalmazást a dotnet new konzolsablon parancsával.

    dotnet new console
    
  3. Importálja a Microsoft.Azure.Cosmos NuGet-csomagot a dotnet 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.

  4. Importálja a Azure.Identity NuGet-csomagot.

    dotnet add package Azure.Identity --version 1.*
    
  5. Hozza létre a projektet a dotnet build paranccsal.

    dotnet build
    
  6. Nyissa meg a választott integrált fejlesztői környezetet (IDE) ugyanabban a könyvtárban, mint a .NET-konzolalkalmazás.

  7. 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.Cosmosdirektívákat.

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Linq;
    using Microsoft.Azure.Cosmos.Spatial;
    
  8. Adjon hozzá egy másik, a névtérhez tartozó direktívát Azure.Identity .

    using Azure.Identity;
    
  9. Hozzon létre egy új, típusnak DefaultAzureCredentialnevezett credential változót.

    DefaultAzureCredential credential = new();
    
  10. Hozzon létre egy sztringváltozót az Azure Cosmos DB for NoSQL-fiókvégponttal.endpoint

    string endpoint = "<nosql-account-endpoint>";
    
  11. Hozzon létre egy új példányt az CosmosClient átadó osztályból connectionString , és csomagolja egy használatba vételi utasításba.

    using CosmosClient client = new (connectionString);
    
  12. 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ával CosmosClient.GetDatabase , majd a használatával Database.GetContainer. Tárolja az eredményt egy névvel ellátott containerváltozóban.

    var container = client.GetDatabase("cosmicworks").GetContainer("locations");
    
  13. 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.

  1. Hozzon létre egy Office.cs nevű új fájlt. A fájlban adjon hozzá egy használati utasítástMicrosoft.Azure.Cosmos.Spatial, majd hozzon létre egy rekordtípust Office 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.

  2. 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.

  3. 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
    );
    
  4. Mentse a Office.cs, Region.cs és Result.cs fájlokat.

  5. Nyissa meg újra a Program.cs fájlt.

  6. Hozzon létre egy újat Polygon egy nevű mainCampusPolygonvá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),
            })
        }
    );
    
  7. Hozzon létre egy új Region változót mainCampusRegion a sokszög, az egyedi azonosító 1000és a név Main Campushasználatával.

    Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
    
  8. 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}");
    

    Tipp.

    Ez az útmutató a beszúrás helyett upsertet használ, így többször is futtathatja a szkriptet anélkül, hogy ütközést okozna az egyedi azonosítók között. Az upsert műveletekkel kapcsolatos további információkért tekintse meg az elemek létrehozását ismertető témakört.

  9. Hozzon létre egy új Point , elnevezett változót headquartersPoint. Ezzel a változóval hozzon létre egy új Office változót headquartersOffice a pont, az egyedi azonosító 0001és a név Headquartershasználatával.

    Point headquartersPoint = new (-122.12827, 47.63980);
    Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
    
  10. Hozzon létre egy másik Point , elnevezett változót researchPoint. Ezzel a változóval hozzon létre egy másikOffice, a megfelelő pont, az egyedi azonosító 0002és a név Research and Developmenthasználatával elnevezett researchOffice változót.

    Point researchPoint = new (-96.84369, 46.81298);
    Office researchOffice = new ("0002", "Research and Development", researchPoint);
    
  11. Hozzon létre egy TransactionalBatch to-upsert mindkét Office 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.

  12. Mentse a Program.cs fájlt.

  13. 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.

  1. Nyissa meg a Program.cs fájlt.

  2. Hozzon létre egy új string , a lekérdezéssel elnevezett nosql 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 a SELECT záradékokban.

  3. Hozzon létre egy új QueryDefinition változót, query amely paraméterként használja a nosqlString változót. Ezután a QueryDefinition.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));
    
  4. Hozzon létre egy új iterátort az Result általános típus és a query 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.

  5. Mentse a Program.cs fájlt.

  6. 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
  1. Nyissa meg a Program.cs fájlt.

  2. Kérje le az Region elemet a tárolóból egyedi azonosítóval 1000 , és tárolja azt egy nevesített regionváltozóban.

    Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
    
  3. 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:

    1. A bővítménymetódussal csak azokkal Queryable.Where<> egyenértékű elemekre category szűrhet "business-office".

    2. A szűrő ismételt használatával Queryable.Where<> csak a változó tulajdonságán location belüli helyekre szűrhet a region használatávalGeometry.Within().

    3. 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.

  4. 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}");
        }
    }
    
  5. Mentse a Program.cs fájlt.

  6. 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.

  1. 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>"
    
  2. 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"
    

Következő lépések