فهرسة بيانات موقع GeoJSON والاستعلام فيها في Azure Cosmos DB ل NoSQL
ينطبق على: NoSQL
تسمح لك البيانات الجغرافية المكانية في Azure Cosmos DB ل NoSQL بتخزين معلومات الموقع وتنفيذ الاستعلامات الشائعة، بما في ذلك على سبيل المثال لا الحصر:
- العثور على ما إذا كان الموقع ضمن منطقة محددة
- قياس المسافة بين موقعين
- تحديد ما إذا كان المسار يتقاطع مع موقع أو منطقة
يستعرض هذا الدليل عملية إنشاء بيانات جيوفضائية، وفهرسة البيانات، ثم الاستعلام عن البيانات في حاوية.
المتطلبات الأساسية
- حساب Azure Cosmos DB ل NoSQL موجود.
- إذا لم يكن لديك اشتراك Azure، فجرب Azure Cosmos DB ل NoSQL مجانا.
- إذا كان لديك اشتراك Azure موجود، فبادر بإنشاء حساب Azure Cosmos DB جديد ل NoSQL.
- أحدث إصدار من .NET.
- أحدث إصدار من Azure CLI.
- إذا كنت تستخدم تثبيتا محليا، فسجل الدخول إلى Azure CLI باستخدام
az login
الأمر .
- إذا كنت تستخدم تثبيتا محليا، فسجل الدخول إلى Azure CLI باستخدام
إنشاء الحاوية ونهج الفهرسة
تتضمن جميع الحاويات نهج فهرسة افتراضيا سيقوم بفهرسة البيانات الجغرافية المكانية بنجاح. لإنشاء نهج فهرسة مخصص، أنشئ حسابا وحدد ملف JSON مع تكوين النهج. في هذا القسم، يتم استخدام فهرس مكاني مخصص لحاوية تم إنشاؤها حديثا.
افتح terminal.
إنشاء متغير shell لاسم حساب Azure Cosmos DB الخاص بك ومجموعة الموارد NoSQL.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
إنشاء قاعدة بيانات جديدة باسم
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
أنشئ ملف JSON جديدا باسم index-policy.json وأضف كائن JSON التالي إلى الملف.
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ], "spatialIndexes": [ { "path": "/location/*", "types": [ "Point", "Polygon" ] } ] }
استخدم
az cosmosdb sql container create
لإنشاء حاوية جديدة باسمlocations
بمسار مفتاح القسم ل/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
وأخيرا، احصل على نقطة نهاية الحساب لحسابك باستخدام
az cosmosdb show
واستعلام JMESPath.az cosmosdb show \ --resource-group "<resource-group-name>" \ --name "<nosql-account-name>" \ --query "documentEndpoint"
سجل نقطة نهاية الحساب حيث ستحتاج إلى ذلك في القسم التالي.
إنشاء تطبيق وحدة تحكم .NET SDK
يوفر .NET SDK ل Azure Cosmos DB ل NoSQL فئات لعناصر GeoJSON الشائعة. استخدم SDK هذا لتبسيط عملية إضافة كائنات جغرافية إلى الحاوية الخاصة بك.
افتح محطة طرفية في دليل فارغ.
إنشاء تطبيق .NET جديد باستخدام
dotnet new
الأمر مع قالب وحدة التحكم .dotnet new console
استيراد حزمة
Microsoft.Azure.Cosmos
NuGet باستخدامdotnet add package
الأمر .dotnet add package Microsoft.Azure.Cosmos --version 3.*
تحذير
لا يقوم إطار عمل الكيان حاليا بالبيانات المكانية في Azure Cosmos DB ل NoSQL. استخدم أحد Azure Cosmos DB ل NoSQL SDKs لدعم GeoJSON الذي تم كتابته بقوة.
استيراد حزمة
Azure.Identity
NuGet.dotnet add package Azure.Identity --version 1.*
قم بإنشاء المشروع باستخدام الأمر
dotnet build
.dotnet build
افتح بيئة المطور المتكاملة (IDE) التي تختارها في نفس الدليل مثل تطبيق وحدة تحكم .NET.
افتح ملف Program.cs الذي تم إنشاؤه حديثا واحذف أي تعليمة برمجية موجودة. أضف استخدام التوجيهات لمساحات
Microsoft.Azure.Cosmos
Microsoft.Azure.Cosmos.Linq
الأسماء و وMicrosoft.Azure.Cosmos.Spatial
.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Spatial;
أضف توجيها آخر باستخدام لمساحة
Azure.Identity
الاسم.using Azure.Identity;
إنشاء متغير جديد يسمى
credential
من النوعDefaultAzureCredential
.DefaultAzureCredential credential = new();
إنشاء متغير سلسلة باسم
endpoint
مع نقطة نهاية حساب Azure Cosmos DB ل NoSQL.string endpoint = "<nosql-account-endpoint>";
إنشاء مثيل جديد للفئة التي
CosmosClient
تمر وتغليفهاconnectionString
في عبارة استخدام.using CosmosClient client = new (connectionString);
استرداد مرجع إلى الحاوية التي تم إنشاؤها مسبقا (
cosmicworks/locations
) في حساب Azure Cosmos DB ل NoSQL باستخدامCosmosClient.GetDatabase
ثمDatabase.GetContainer
. قم بتخزين النتيجة في متغير يسمىcontainer
.var container = client.GetDatabase("cosmicworks").GetContainer("locations");
احفظ ملف Program.cs.
إضافة بيانات جغرافية مكانية
يتضمن .NET SDK أنواعا متعددة في Microsoft.Azure.Cosmos.Spatial
مساحة الاسم لتمثيل كائنات GeoJSON الشائعة. تبسط هذه الأنواع عملية إضافة معلومات موقع جديدة إلى العناصر الموجودة في حاوية.
إنشاء ملف جديد باسم Office.cs. في الملف، أضف توجيه استخدام إلى
Microsoft.Azure.Cosmos.Spatial
ثم قم بإنشاءOffice
نوع سجل بهذه الخصائص:النوع الوصف القيمة الافتراضية معرف string
معرِّف فريد الاسم string
اسم المكتب مكان Point
نقطة جغرافية GeoJSON الفئة string
قيمة مفتاح القسم business-office
using Microsoft.Azure.Cosmos.Spatial; public record Office( string id, string name, Point location, string category = "business-office" );
إنشاء ملف جديد آخر باسم Region.cs. أضف نوع سجل آخر باسم
Region
بهذه الخصائص:النوع الوصف القيمة الافتراضية معرف string
معرِّف فريد الاسم string
اسم المكتب مكان Polygon
شكل جغرافي GeoJSON الفئة string
قيمة مفتاح القسم business-region
using Microsoft.Azure.Cosmos.Spatial; public record Region( string id, string name, Polygon location, string category = "business-region" );
إنشاء ملف جديد آخر باسم Result.cs. أضف نوع سجل باسم
Result
لهذين الخاصيتين:النوع الوصف الاسم string
اسم النتيجة المتطابقة مقاييس المسافة decimal
المسافة بالكيلومترات public record Result( string name, decimal distanceKilometers );
احفظ ملفات Office.cs Region.cs وملفات Result.cs.
افتح الملف Program.cs مرة أخرى.
إنشاء جديد
Polygon
في متغير يسمىmainCampusPolygon
.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), }) } );
أنشئ متغيرا جديدا
Region
باسمmainCampusRegion
باستخدام المضلع والمعرف الفريد1000
والاسمMain Campus
.Region mainCampusRegion = new ("1000", "Main Campus", mainCampusPolygon);
استخدم
Container.UpsertItemAsync
لإضافة المنطقة إلى الحاوية. اكتب معلومات المنطقة إلى وحدة التحكم.await container.UpsertItemAsync<Region>(mainCampusRegion); Console.WriteLine($"[UPSERT ITEM]\t{mainCampusRegion}");
تلميح
يستخدم هذا الدليل upsert بدلا من الإدراج حتى تتمكن من تشغيل البرنامج النصي عدة مرات دون التسبب في تعارض بين المعرفات الفريدة. لمزيد من المعلومات حول عمليات upsert، راجع إنشاء العناصر.
إنشاء متغير جديد
Point
باسمheadquartersPoint
. استخدم هذا المتغير لإنشاء متغير جديدOffice
يسمىheadquartersOffice
باستخدام النقطة والمعرف الفريد0001
والاسمHeadquarters
.Point headquartersPoint = new (-122.12827, 47.63980); Office headquartersOffice = new ("0001", "Headquarters", headquartersPoint);
إنشاء متغير آخر
Point
باسمresearchPoint
. استخدم هذا المتغير لإنشاء متغير آخرOffice
يسمىresearchOffice
باستخدام النقطة المقابلة والمعرف الفريد0002
والاسمResearch and Development
.Point researchPoint = new (-96.84369, 46.81298); Office researchOffice = new ("0002", "Research and Development", researchPoint);
TransactionalBatch
إنشاء لإضافة كلاOffice
المتغيرين كمعاملة واحدة. بعد ذلك، اكتب معلومات كلا المكتبين إلى وحدة التحكم.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}");
إشعار
لمزيد من المعلومات حول المعاملات، راجع عمليات دفعة المعاملات.
احفظ ملف Program.cs.
تشغيل التطبيق في محطة طرفية باستخدام
dotnet run
. لاحظ أن إخراج تشغيل التطبيق يتضمن معلومات حول العناصر الثلاثة التي تم إنشاؤها حديثا.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 }
الاستعلام عن البيانات الجغرافية المكانية باستخدام استعلام NoSQL
يمكن استخدام الأنواع في Microsoft.Azure.Cosmos.Spatial
مساحة الاسم كإدخالات إلى استعلام ذو معلمات NoSQL لاستخدام الدوال المضمنة مثل ST_DISTANCE
.
افتح ملف Program.cs.
يتم استخدام إنشاء متغير جديد
string
باسمnosql
مع الاستعلام في هذا القسم لقياس المسافة بين النقاط.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 ";
إنشاء متغير جديد
QueryDefinition
يسمىquery
باستخدامnosqlString
المتغير كمعلمة. ثم استخدم الأسلوب بطلاقةQueryDefinition.WithParameter
عدة مرات لإضافة هذه المعلمات إلى الاستعلام:القيمة @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));
إنشاء مكرر جديد باستخدام
Container.GetItemQueryIterator<>
والنوعResult
العام والمتغيرquery
. بعد ذلك، استخدم مجموعة من الوقت وحلقة foreach للتكرار على جميع النتائج في كل صفحة من النتائج. إخراج كل نتيجة إلى وحدة التحكم.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}"); } }
إشعار
لمزيد من المعلومات حول تعداد نتائج الاستعلام، راجع عناصر الاستعلام.
احفظ ملف Program.cs.
قم بتشغيل التطبيق مرة أخرى في محطة طرفية باستخدام
dotnet run
. لاحظ أن الإخراج يتضمن الآن نتائج الاستعلام.dotnet run
[DISTANCE KM] Result { name = Headquarters, distanceKilometers = 3.34 } [DISTANCE KM] Result { name = Research and Development, distanceKilometers = 1907.43 }
الاستعلام عن البيانات الجغرافية المكانية باستخدام LINQ
تدعم وظيفة LINQ إلى NoSQL في .NET SDK تضمين الأنواع الجغرافية المكانية في تعبيرات الاستعلام. علاوة على ذلك، يتضمن SDK أساليب الامتداد التي تعين إلى وظائف مضمنة مكافئة:
أسلوب الملحق | دالة مضمنة |
---|---|
Distance() |
ST_DISTANCE |
Intersects() |
ST_INTERSECTS |
IsValid() |
ST_ISVALID |
IsValidDetailed() |
ST_ISVALIDDETAILED |
Within() |
ST_WITHIN |
افتح ملف Program.cs.
Region
استرداد العنصر من الحاوية بمعرف فريد من1000
وتخزينه في متغير يسمىregion
.Region region = await container.ReadItemAsync<Region>("1000", new PartitionKey("business-region"));
Container.GetItemLinqQueryable<>
استخدم الأسلوب للحصول على LINQ قابل للاستعلام، وبناء استعلام LINQ بطلاقة عن طريق تنفيذ هذه الإجراءات الثلاثة:استخدم أسلوب الملحق
Queryable.Where<>
للتصفية إلى العناصر التي لهاcategory
ما يعادل"business-office"
فقط .استخدم
Queryable.Where<>
مرة أخرى للتصفية إلى المواقع داخلregion
خاصية المتغيرlocation
فقط باستخدامGeometry.Within()
.ترجمة تعبير LINQ إلى مكرر موجز باستخدام
CosmosLinqExtensions.ToFeedIterator<>
.
var regionIterator = container.GetItemLinqQueryable<Office>() .Where(o => o.category == "business-office") .Where(o => o.location.Within(region.location)) .ToFeedIterator<Office>();
هام
في هذا المثال، تحتوي خاصية موقع المكتب على نقطة، وتحتوي خاصية الموقع في المنطقة على مضلع.
ST_WITHIN
تحديد ما إذا كانت نقطة المكتب داخل مضلع المنطقة.استخدم مجموعة من الوقت وحلقة foreach للتكرار على جميع النتائج في كل صفحة من النتائج. إخراج كل نتيجة إلى وحدة التحكم.
while (regionIterator.HasMoreResults) { var response = await regionIterator.ReadNextAsync(); foreach (var office in response) { Console.WriteLine($"[IN REGION]\t{office}"); } }
احفظ ملف Program.cs.
قم بتشغيل التطبيق مرة أخيرة في محطة طرفية باستخدام
dotnet run
. لاحظ أن الإخراج يتضمن الآن نتائج الاستعلام الثاني المستند إلى LINQ.dotnet run
[IN REGION] Office { id = 0001, name = Headquarters, location = Microsoft.Azure.Cosmos.Spatial.Point, category = business-office }
تنظيف الموارد
قم بإزالة قاعدة البيانات بعد إكمال هذا الدليل.
افتح محطة طرفية وأنشئ متغير shell لاسم حسابك ومجموعة الموارد.
# Variable for resource group name resourceGroupName="<name-of-your-resource-group>" # Variable for account name accountName="<name-of-your-account>"
استخدم
az cosmosdb sql database delete
لإزالة قاعدة البيانات.az cosmosdb sql database delete \ --resource-group "<resource-group-name>" \ --account-name "<nosql-account-name>" \ --name "cosmicworks"