قواعد بيانات MongoDB في دلفي
#1
السلام عليكم ورحمة الله

اردت ان اعرض تجربتي مع هذا النوع من قواعد البيانات ومع دلفي 10.4 حيث يقدم مجموعة من المكونات لاجل هذا الغرض

بداية وقبل ان نخوض في ذلك دعونا نتطرق الى بعض الاشياء ، هي من قواعد البيانات التي يطلقون عليها NoSQL اي لا تحتاج الى استعلامات
او بمعنى اخر لا تدعم الـ SQL المعروفة 

فبدلا من

كود :
Select * from school where gender=male

سوف تكتب

كود :
db.getCollection('school').find({gender: {$eq: "Male"}})

طبعا التعبير الاول افضل واسهل كثيرا ومفهوم اكثر فقصة NoSQL عيب وليست ميزة

وبالمقابل هي قواعد بيانات غير علائقية لنرى هذا السجل مثلا

كود :
{     "_id" : ObjectId("5eff95673729661444dabdc1"),     "mname" : "ALI Ahmad",     "age" : 47.0,     "city" : "TRIBOLI",     "address" : {         "city" : "TRIBOLI",         "state" : "ST-34",         "active" : false     },     "books" : [         {             "title" : "ziro",             "pages" : 100.0         },         {             "title" : "trees",             "pages" : 200.0         },         {             "title" : "houses",             "pages" : 140.0         }     ],     "photo" : BinData(0, "/9j/4AAQSkZJRgABAgEAAAAAAAD/7gAO.. 47105 more bytes") }


في قواعد البيانات العلائقية كنت ستحتاج الى انشاء جدول اخر باسم Books لتضع فيع الكتب وصفحاتها اما هنا فمحشورة هذه البيانات بداخل نفس السجل في شكل مصفوفة كما بالشكل التالي:

كود :
"books" : [         {             "title" : "ziro",             "pages" : 100.0         },         {             "title" : "trees",             "pages" : 200.0         },         {             "title" : "houses",             "pages" : 140.0         }     ]

عندما فكرت بهذا الاسلوب اعتقدت ان الامر سيكون اسهل من استخدام جمل استعلام لجلب جداول مترابطة ولكن المشكلة انني وجدت انك تحتاج الى بعض الجهد للتعامل مع هذه الـ Arrays في قرائتها وتعديلها واضافتها يوازي الجهد المبدول في التعامل مع الجداول العلائقية


ايضا في حقول الترقيم التلقائي نحن نبداء بالرقم 1 ثم 2 وهذه القاعدة تبداء وتستخدم رقم طويل مثل 5eff95673729661444dabdc1 مما يبدوا لي انه سوف ياخذ حجم اكبر من الذاكرة .
ايضا هنا لا يمكن التعويض عن القيمة برقم الفهرس مثل ان تكون لديك في جدول المؤهلات المؤهل العلمي دراسات عليا جامعية في علوم الكمبيوتر يمكننا التعويض عنها برقم التعريف في جدول اخر وليكن مثلا 5 حتى لا نكرر نفس البيانات اما بهذه القاعدة فيتكرر الاسم وهو ما يزيد في حجم الذاكرة ايضا .

على العموم في الدلفي يوجد مكون الاتصال FDConnection1 ومكون FDMongoQuery1 للاتصال بالـ Collection والتي هي تماثل السجلات 
ويمكن ربط   [size=small]FDMongoQuery1 [/size] بالمكون DataSource1

هناك طرق لانشاء قاعدة البيانات واضافة لها شكل الـ Collection المطلوب من داخل الدلفي لم ابحث فيه كثيرا ولكن استخدمت برنامج Studio 3T لاجل ذلك كما توجد العديد من البرامج للتعامل مع هذا النوع من قواعد البيانات .

من داخل هذا البرنامج يمكننا رؤية هذا التجميع للسجل كما بالشكل التالي :

[صورة: attachment.php?aid=4278]


.jpg   1.jpg (الحجم : 44.4 ك ب / التحميلات : 92)

من داخل الدلفي كانت هناك بعض المكونات استطاعت ان تفهم التركيبة المعقدة وهناك مكونات لم تستطيع ان تفهم هذا
انظروا للشكل التالي :
[صورة: attachment.php?aid=4279]

.jpg   2.jpg (الحجم : 134.05 ك ب / التحميلات : 90)

مكون الشبكة السفلي استطاع ان يفهم ويظهر المصفوفة Books بمجرد النقر عليها بينما العلوي لم يفعل
لدينا حقول تحت ال Record بالاسم address هي ليست مصفوفة وانما مجموعة من الحقول تحت اسم واحد مثل الـ Record تماما
نلاحظ ان المكون رتبها بحسب ما وجدها وما فهمها تماما اما المكون العلوي لم يستطع ذلط

وليس هذا وحسب المكون السفلي من شركة Stylecontrol تستطيع ان تغير في قيم هذه الحقول اما العلوي فلا يستطيع .

من ناحية السرعة اعتقد ان فيها سرعة كما يقولون .
هذه بداية وفي الشرح القادم سوف نستعرض المثال ونرفق مشروع كمثال .
قل: اللهم فاطِرَ السماوات والأرض عالم الغيبِ والشهادة، ربَّ كُلِّ شَيءٍ ومَلِيكَه، أَشْهد أن لا إله إلا أنت، أعوذ بك من شرِّ نفسي وشرِّ الشيطان وشِرْكِهِ وأن أقترف على نفسي سوءًا أو أجرُّه إلى مسلم
[-] كل من 3 users say قال شكرا ل Delphi4Us على المشاركة المفيدة
  • ALG2009, mobile, sathex
الرد
#2
وعليك السلام و رحمة الله تعالى و بركاته

في الحقيقة قاعدة بيانات تستحق الاهتمام ، من الناحية العملية في السرعة و الأداء

* لكن متى احتاج إليها ، بالنسبة لاستضافات المواقع ربنا ، أي موقع له مستخدمين بالآلاف ، أما نحن برنامج يعمل على شبكة محلية أي برنامج مسير قواعد بيانات يفي بالغرض

* أما بالنسبتي لي لازم مرور عليها ، ربما نحتاجها يوما ما

* ارجوا مشاركتنا بالتجربة من تعامل معها بالدلفي

MongoDB In 30 Minutes
[-] كل من 2 users say قال شكرا ل larbiparadox على المشاركة المفيدة
  • Delphi4Us, أبو معاذ
الرد
#3
[صورة: MongoDB.png]

توجد مكتبات كثيرة للتعامل مع هذا النوع من قواعد البيانات بشكل يدوي وليس ربط بالمكونات كما اوضحت ببداية المنشور
على سبيل المثال لا الحصر هذه مكتبة

https://github.com/grijjy/DelphiMongoDB

للاتصال بقاعدة البيانات

كود :
var   Client: IgoMongoClient;   Database: IgoMongoDatabase;   Collection: IgoMongoCollection; begin   Client := TgoMongoClient.Create('localhost');   Database := Client.GetDatabase('test');   Collection := Database.GetCollection('restaurants'); end;

لاضافة مستند او سجل

كود :
var   Line: String;   Doc: TgoBsonDocument;   DataSet: TList<TgoBsonDocument>;   Collection: IgoMongoCollection; begin   ..Initialization of Stream, Dataset and Collection not shown here..   Reader := TStreamReader.Create(Stream, TEncoding.UTF8);   while (not Reader.EndOfStream) do   begin     Line := Reader.ReadLine;     Doc := TgoBsonDocument.Parse(Line);     Dataset.Add(Doc);   end;   Collection.InsertMany(Dataset); end;


لاضافة مستند او سجل بشكل يدوي

كود :
procedure TTestInsertPrimer.InsertADocument; var   Doc: TgoBsonDocument;   Collection: IgoMongoCollection; begin   Doc := TgoBsonDocument.Create()     .Add('address', TgoBsonDocument.Create()                       .Add('street', '2 Avenue')                       .Add('zipcode', '10075')                       .Add('building', '1480')                       .Add('coord', TgoBsonArray.Create([73.9557413, 40.7720266])))     .Add('borough', 'Manhattan')     .Add('cuisine', 'Italian')     .Add('grades', TgoBsonArray.Create([       TgoBsonDocument.Create()         .Add('date', EncodeDateTime(2014, 10, 1, 0, 0, 0, 0))         .Add('grade', 'A')         .Add('score', 11),       TgoBsonDocument.Create()         .Add('date', EncodeDateTime(2014, 1, 6, 0, 0, 0, 0))         .Add('grade', 'B')         .Add('score', 17)]))     .Add('name', 'Vella')     .Add('restaurant_id', '941704620');   Collection := Database.GetCollection('restaurants');   Collection.InsertOne(Doc); end;


للاستعلام عن سجل او مستند

كود :
procedure TTestQueryPrimer.QueryAll; var   Collection: IgoMongoCollection;   Count: Integer;   Doc: TgoBsonDocument; begin   Collection := Database.GetCollection('restaurants');   Count := 0;   for Doc in Collection.Find() do     Inc(Count);   Assert.AreEqual(25359, Count); end;

فلترة البيانات

كود :
procedure TTestQueryPrimer.QueryTopLevelField; begin   ...   for Doc in Collection.Find(TgoMongoFilter.Eq('borough', 'Manhattan')) do     Inc(Count);       Assert.AreEqual(10259, Count); end;

كود :
procedure TTestQueryPrimer.LogicalAnd; begin   ...   for Doc in Collection.Find(     TgoMongoFilter.Eq('cuisine', 'Italian') and     TgoMongoFilter.Eq('address.zipcode', '10075')   ) do     Inc(Count);   Assert.AreEqual(15, Count); end;

ترتيب البيانات

كود :
for Doc in Collection.Find(   TgoMongoFilter.Empty,   TgoMongoSort.Ascending('borough') +   TgoMongoSort.Ascending('address.zipcode')) do


حذف البيانات

كود :
procedure TTestRemovePrimer.RemoveMatchingDocuments; var   Collection: IgoMongoCollection;   Count: Integer; begin   Collection := Database.GetCollection('restaurants');   Count := Collection.DeleteMany(TgoMongoFilter.Eq('borough', 'Manhattan'));   Assert.AreEqual(10259, Count); end;

تحديث بيانات

كود :
Collection.UpdateOne(   TgoMongoFilter.Eq('restaurant_id', '41156888'),   TgoMongoUpdate.Init     .&Set('address.street', 'East 31st Street')     .CurrentDate('lastModified));

يوجد ايضا مكونات اخرى ولكل مكتبة اسلوب وطريقة يبقى الاختيار على المستخدم لاختيار الانسب 

MongoEngine

MongoKit

MongoKat

Monary

Django-mongonaut

TxMongo

yunnet
قل: اللهم فاطِرَ السماوات والأرض عالم الغيبِ والشهادة، ربَّ كُلِّ شَيءٍ ومَلِيكَه، أَشْهد أن لا إله إلا أنت، أعوذ بك من شرِّ نفسي وشرِّ الشيطان وشِرْكِهِ وأن أقترف على نفسي سوءًا أو أجرُّه إلى مسلم
[-] كل من 3 users say قال شكرا ل Delphi4Us على المشاركة المفيدة
  • mobile, sathex, أبو معاذ
الرد
#4
وعليكم السلام ورحمة الله وبركاته

شكرا لك على مشاركة تجربتك .
مثل هته الاشكال التي تشعرك بنسمة Json لن اتوق اليها ابدا Smile
اذا تاملت في قواعد البيانات سترى ان FireBase ستكون مستقبل كل المشاريع ومع cloud لن تحتاج الا لقرص تنصب فيه نظام تشغيلك والله اعلم
لأستهلنّ الصعب أو أدرك المنى    فما انقادت الآمال إلاّ لصابر
[-] كل من 2 users say قال شكرا ل mobile على المشاركة المفيدة
  • Delphi4Us, أبو معاذ
الرد
#5
اجل انا ايضا لم تشدني كثيرا حتى الان لازلت اجرب
على العموم وجدت ايضا ان بالامكان استخدام جمل الاستعلام بشكل عادي مع بعض المكونات

كود :
FDConnection1.Name := 'MongoDBConnection'; FDConnection1.DriverName := 'CData.Fire.MongoDB'; with FDConnection1.Params as   TFDPhysCDataMongoDBConnectionDefParams do begin ... end; FDConnection1.Connected := true; FDQuery1.Active := true; FDQuery1.Open('select * from DocumentDB where id = ''...'''); ...

وهنا درس عن طريقة الربط بواسطة هذه المكونات


DataBind Controls to MongoDB Data in Delphi
قل: اللهم فاطِرَ السماوات والأرض عالم الغيبِ والشهادة، ربَّ كُلِّ شَيءٍ ومَلِيكَه، أَشْهد أن لا إله إلا أنت، أعوذ بك من شرِّ نفسي وشرِّ الشيطان وشِرْكِهِ وأن أقترف على نفسي سوءًا أو أجرُّه إلى مسلم
[-] كل من 2 users say قال شكرا ل Delphi4Us على المشاركة المفيدة
  • mobile, sathex
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم