Mengindeks dan mengkueri data lokasi GeoJSON di Azure Cosmos DB untuk NoSQL
BERLAKU UNTUK: NoSQL
Data geospasial di Azure Cosmos DB for NoSQL memungkinkan Anda menyimpan informasi lokasi dan melakukan kueri umum, termasuk tetapi tidak terbatas pada:
- Menemukan apakah lokasi berada dalam area yang ditentukan
- Mengukur jarak antara dua lokasi
- Menentukan apakah jalur bersinggungan dengan lokasi atau area
Panduan ini memandu melalui proses pembuatan data geospasial, mengindeks data, lalu mengkueri data dalam kontainer.
Prasyarat
- Akun Azure Cosmos DB for NoSQL yang sudah ada.
- Jika Anda tidak memiliki langganan Azure, Coba Azure Cosmos DB untuk NoSQL gratis.
- Jika Anda memiliki langganan Azure yang sudah ada, buat akun Azure Cosmos DB for NoSQL baru.
- Versi terbaru .NET.
- Versi terbaru Azure CLI.
- Jika Anda menggunakan penginstalan lokal, masuk ke Azure CLI dengan menggunakan
az login
perintah .
- Jika Anda menggunakan penginstalan lokal, masuk ke Azure CLI dengan menggunakan
Membuat kebijakan kontainer dan pengindeksan
Semua kontainer menyertakan kebijakan pengindeksan default yang akan berhasil mengindeks data geospasial. Untuk membuat kebijakan pengindeksan yang disesuaikan, buat akun dan tentukan file JSON dengan konfigurasi kebijakan. Di bagian ini, indeks spasial kustom digunakan untuk kontainer yang baru dibuat.
Buka terminal.
Buat variabel shell untuk nama akun Dan grup sumber daya Azure Cosmos DB for NoSQL Anda.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Buat database baru bernama
cosmicworks
menggunakanaz cosmosdb sql database create
.az cosmosdb sql database create \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks" \ --throughput 400
Buat file JSON baru bernama index-policy.json dan tambahkan objek JSON berikut ke file.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }
Gunakan
az cosmosdb sql container create
untuk membuat kontainer baru bernamalocations
dengan jalur kunci partisi ./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.json
Terakhir, dapatkan titik akhir akun untuk akun Anda menggunakan
az cosmosdb show
dan kueri JMESPath.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"
Rekam titik akhir akun karena Anda akan membutuhkannya di bagian berikutnya.
Membuat aplikasi konsol .NET SDK
.NET SDK untuk Azure Cosmos DB for NoSQL menyediakan kelas untuk objek GeoJSON umum. Gunakan SDK ini untuk menyederhanakan proses penambahan objek geografis ke kontainer Anda.
Buka terminal di direktori kosong.
Buat aplikasi .NET baru dengan menggunakan perintah
dotnet new
dengan templat konsol.dotnet new console
Microsoft.Azure.Cosmos
Impor paket NuGet menggunakandotnet add package
perintah .dotnet add package Microsoft.Azure.Cosmos --version 3.*
Peringatan
Kerangka Kerja Entitas saat ini tidak melakukan data spasial di Azure Cosmos DB untuk NoSQL. Gunakan salah satu Azure Cosmos DB untuk NoSQL SDK untuk dukungan GeoJSON yang sangat diketik.
Azure.Identity
Impor paket NuGet.dotnet add package Azure.Identity --version 1.*
Buat proyek dengan perintah
dotnet build
.dotnet build
Buka lingkungan pengembang terintegrasi (IDE) pilihan Anda di direktori yang sama dengan aplikasi konsol .NET Anda.
Buka file Program.cs yang baru dibuat dan hapus kode yang ada. Tambahkan menggunakan direktif untuk
Microsoft.Azure.Cosmos
namespace ,Microsoft.Azure.Cosmos.Linq
, danMicrosoft.Azure.Cosmos.Spatial
.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;
Tambahkan yang lain menggunakan direktif untuk
Azure.Identity
namespace layanan.using Azure.Identity;
Buat variabel baru bernama
credential
jenisDefaultAzureCredential
.DefaultAzureCredential credential = new();
Buat variabel string bernama
endpoint
dengan Titik akhir akun Azure Cosmos DB for NoSQL Anda.string endpoint = "<nosql-account-endpoint>";
Buat instans baru kelas yang
CosmosClient
melewaticonnectionString
dan membungkusnya dalam pernyataan penggunaan.using CosmosClient client = new (connectionString);
Ambil referensi ke kontainer yang dibuat sebelumnya (
cosmicworks/locations
) di akun Azure Cosmos DB for NoSQL dengan menggunakanCosmosClient.GetDatabase
laluDatabase.GetContainer
. Simpan hasilnya di variabel bernamacontainer
.var container = client.GetDatabase("cosmicworks").GetContainer("locations");
Simpan file Program.cs.
Menambahkan data geospasial
.NET SDK menyertakan beberapa jenis di Microsoft.Azure.Cosmos.Spatial
namespace untuk mewakili objek GeoJSON umum. Jenis ini menyederhanakan proses penambahan informasi lokasi baru ke item dalam kontainer.
Buat file baru bernama Office.cs. Dalam file, tambahkan direktif menggunakan ke
Microsoft.Azure.Cosmos.Spatial
lalu buatOffice
jenis catatan dengan properti ini:Tipe Deskripsi Nilai default id string
Pengidentifikasi unik nama string
Nama kantor Lokasi Point
Titik geografis GeoJSON category string
Nilai kunci partisi business-office
using Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );
Catatan
Catatan ini mencakup properti yang
Point
mewakili posisi tertentu di GeoJSON. Untuk informasi selengkapnya, lihat GeoJSON Point.Buat file baru lain bernama Region.cs. Tambahkan tipe catatan lain bernama
Region
dengan properti ini:Tipe Deskripsi Nilai default id string
Pengidentifikasi unik nama string
Nama kantor Lokasi Polygon
Bentuk geografis GeoJSON category string
Nilai kunci partisi business-region
using Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );
Buat file baru lain bernama Result.cs. Tambahkan tipe catatan bernama
Result
dengan dua properti ini:Tipe Deskripsi nama string
Nama hasil yang cocok distanceKilometers decimal
Jarak dalam kilometer public record Result( string name, decimal distanceKilometers );
Simpan file Office.cs, Region.cs, dan Result.cs.
Membuka file Program.cs lagi.
Buat baru
Polygon
dalam variabel bernamamainCampusPolygon
.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), }) } );
Buat variabel baru
Region
bernamamainCampusRegion
menggunakan poligon, pengidentifikasi1000
unik , dan namaMain Campus
.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
Gunakan
Container.UpsertItemAsync
untuk menambahkan wilayah ke kontainer. Tulis informasi wilayah ke konsol.await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");
Tip
Panduan ini menggunakan upsert alih-alih menyisipkan sehingga Anda dapat menjalankan skrip beberapa kali tanpa menyebabkan konflik antara pengidentifikasi unik. Untuk informasi selengkapnya tentang operasi upsert, lihat membuat item.
Buat variabel baru
Point
bernamaheadquartersPoint
. Gunakan variabel tersebut untuk membuat variabel baruOffice
bernamaheadquartersOffice
menggunakan titik , pengidentifikasi0001
unik , dan namaHeadquarters
.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
Buat variabel lain
Point
bernamaresearchPoint
. Gunakan variabel tersebut untuk membuat variabel lainOffice
bernamaresearchOffice
menggunakan titik yang sesuai, pengidentifikasi0002
unik , dan namaResearch and Development
.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);
Buat
TransactionalBatch
untuk meningkatkan keduaOffice
variabel sebagai satu transaksi. Kemudian, tulis informasi kedua kantor ke konsol.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}");
Catatan
Untuk informasi selengkapnya tentang transaksi, lihat operasi batch transaksional.
Simpan file Program.cs.
Jalankan aplikasi di terminal menggunakan
dotnet run
. Amati bahwa output eksekusi aplikasi mencakup informasi tentang tiga item yang baru dibuat.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 }
Mengkueri data geospasial menggunakan kueri NoSQL
Jenis di Microsoft.Azure.Cosmos.Spatial
namespace dapat digunakan sebagai input ke kueri berparameter NoSQL untuk menggunakan fungsi bawaan seperti ST_DISTANCE
.
Buka file Program.cs.
Buat variabel baru
string
bernamanosql
dengan kueri digunakan di bagian ini untuk mengukur jarak antar titik.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 ";
Buat variabel baru
QueryDefinition
bernamaquery
menggunakannosqlString
variabel sebagai parameter. Kemudian gunakanQueryDefinition.WithParameter
metode fasih beberapa kali untuk menambahkan parameter ini ke kueri:Nilai @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));
Buat iterator baru menggunakan
Container.GetItemQueryIterator<>
,Result
jenis generik, danquery
variabel . Kemudian, gunakan kombinasi perulangan sementara dan foreach untuk melakukan iterasi atas semua hasil di setiap halaman hasil. Keluarkan setiap hasil ke konsol.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}"); } }
Catatan
Untuk informasi selengkapnya tentang menghitung hasil kueri, lihat item kueri.
Simpan file Program.cs.
Jalankan aplikasi lagi di terminal menggunakan
dotnet run
. Amati bahwa output sekarang menyertakan hasil kueri.dotnet run
[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
Mengkueri data geospasial menggunakan LINQ
Fungsionalitas LINQ ke NoSQL di .NET SDK mendukung termasuk jenis geospasial dalam ekspresi kueri. Lebih lanjut, SDK mencakup metode ekstensi yang memetakan ke fungsi bawaan yang setara:
Metode ekstensi | Fungsi bawaan |
---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
Buka file Program.cs.
Region
Ambil item dari kontainer dengan pengidentifikasi1000
unik dan simpan dalam variabel bernamaregion
.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
Container.GetItemLinqQueryable<>
Gunakan metode untuk mendapatkan LINQ yang dapat dikueri, dan buat kueri LINQ dengan lancar dengan melakukan ketiga tindakan ini:Queryable.Where<>
Gunakan metode ekstensi untuk memfilter hanya item dengan yang setara"business-office"
dengancategory
.Gunakan
Queryable.Where<>
lagi untuk memfilter hanya ke lokasi dalamregion
properti variabellocation
menggunakanGeometry.Within()
.Terjemahkan ekspresi LINQ ke iterator umpan menggunakan
CosmosLinqExtensions.ToFeedIterator<>
.
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();
Penting
Dalam contoh ini, properti lokasi kantor memiliki titik, dan properti lokasi wilayah memiliki poligon.
ST_WITHIN
menentukan apakah titik kantor berada dalam poligon wilayah.Gunakan kombinasi perulangan sementara dan foreach untuk melakukan iterasi atas semua hasil di setiap halaman hasil. Keluarkan setiap hasil ke konsol.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }
Simpan file Program.cs.
Jalankan aplikasi untuk terakhir kalinya di terminal menggunakan
dotnet run
. Amati bahwa output sekarang menyertakan hasil kueri berbasis LINQ kedua.dotnet run
[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
Membersihkan sumber daya
Hapus database Anda setelah Anda menyelesaikan panduan ini.
Buka terminal dan buat variabel shell untuk nama akun dan grup sumber daya Anda.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
Gunakan
az cosmosdb sql database delete
untuk menghapus database.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"