استخدام قواعد بيانات مونغو دي بي MongoDB في بايثون

MongoDB هي قاعدة بيانات مستندات Documents مبنية على بنية قابلة للتوسيع Scalable  أصبحت شائعة لدى مطوري برمجيات مختلفة وأصبح اسم مونغو دي بي يتكرر كثيرا عند الحديث عن المنهج الرشيق Agile. حيث تم تصميم MongoDB بشكل أساسي للأشخاص الذين يحتاجون إلى التطوير وإضافة مزايا وتحديث قواعد البيانات الخاصة بتطبيقاتهم بسرعة.

Image result for mongodb


متى يجب أن استخدم مونغو دي بي؟

ينصح باستخدام MongoDB اذا كان هيكل تخزين البيانات الخاص بمشروعك من نمط مستند Document وتعتبر النقاط التالية مهمة لك:

  • مونغو دي بي مجانية ومفتوحة المصدر ولا تحتاج إلى دفع نقود أو الحصول على رخصة لاستخدامها, كما تحظى بدعم فني كبير في مجتمع البرمجيات مفتوحة المصدر.
  • ترغب بتخزين حجم هائل من المستندات وتعطي حركة مرور البيانات أولوية كبيرة في مشروعك.
  • الانتقال إلى البرمجة والتطوير بسرعة وعدم صرف وقت كبير على تصميم وصيانة قواعد البيانات.
  • مونغو دي بي تعمل على جميع البرمجيات وأنظمة التشغيل كما أنا تدعم بشكل كبير التخزين السحابي Cloud متوافقة مع AWS, Azure و Google Cloud.
  • مونغو دي بي مدعومة من لغات البرمجة الشهيرة بشكل كامل.
  •  إذا كنت تعمل على مشروع يحوي بيانات كبيرة وتعطي أولوية لتصميم نظام ETL  Extract, Transform, Load فعّال فبالتأكيد ستكون مونغو دي بي خيار أكثر من مناسب لك.
  • مرة أخرى, مونغو دي بي تعطيك مرونة في تحميل البيانات لذلك لا داعي للقلق حول تصميم Schema وتعريفها بشكل صارم كما اعتدنا في قواعد البيانات العلائقية, حيث تعتمد مونغو دي بي في تخزين البيانات على بيانات مخزنة بصيغة JSON كما سنرى لاحقا في هذه المقالة.
  • شركات كبيرة مثل Bosch, Morgan Stanley , Barclays تستخدم اليوم  مونغو دي بي لإدارة تطبيقاتهم في انترنت الأشياء والألعاب والتطبيقات البنكية وإدارة المحتوى, وكما يقولوا أفعل مثل الكبار (Stand on the shoulders of giants).

مفاهيم هامة في مونغو دي بي

قبل البدء في برمجة تطبيق مونغو دي بي في بايثون، يجب ان نقوم بتعريف ثلاث مصطلحات أساسية في مونغو دي بي تعكس الآلية التي يتم فيها تخزين البيانات. 

المستند Document كما ذكرنا، مونغو دي بي تخزّن جميع البيانات على هيئة مستندات، يمكن النظر إلى المستند على أنه صف Row في جدول في قواعد البيانات التقليدية.

المجموعة Collection هي مجموعة من المستندات, وتقابل المجموعة الجدول Table في قواعد البيانات التقليدية.

قاعدة البيانات Database وهي عدة مجموعات كل منها تحوي عدة مستندات.

مونغو دي بي  في بايثون

يمكن تنصيب مونغو دي بي على جميع أنظمة التشغيل الشائعة, لتنصيب أخر نسخة مستقرة من MongoDB Community على  اوبنتو اتبع التعليمات المذكورة على الرابط الرسمي.

بعد أن نقوم بتنصيب نظام MongoDB نقوم بتنصيب حزمة بايثون الخاصة بالإتصال مع قاعدة البيانات وإجراء العمليات الأساسية عليها, هذه الحزمة في بايثون تدعى pymongo، تستطيع تنصيبها بتنفيذ التعليمة التالية: 

pip install pymongo==3.4.0

لاختبار تنصيب الحزمة بشكل صحيح، قم بتنفيذ التعليمة التالية, اذا لم تظهر أية أخطاء، هذا يعني ان pymongo تم تنصيبها بشكل سليم وأصبحت جاهزة للاستخدام:

import pymongo

إنشاء قاعدة بيانات مونغو دي بي

لإنشاء قاعدة بيانات مونغودي بي ، يجب تحديد اسم قاعدة البيانات التي تود إنشائها ورابط العميل الخاص بمونغو دي بي ، بشكل افتراضي تستطيع في بايثون استخدام التعليمات التالية لإنشاء قاعدة بيانات باسم mydatabase

import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
 

استعراض قواعد البيانات التي تم إنشاؤها، تستطيع استخدام التعليمة التالية

print(myclient.list_database_names())

إنشاء مجموعة Collection مونغو دي بي

لإنشاء مجموعة Collection عبر بايثون، تستطيع استخدام كائن من نمط database وتحديد اسم قاعدة المجموعة التي تريد إنشائها، تذكر ان ذلك شبيه بإنشاء جدول في قاعدة بيانات في قواعد البيانات العلائقية 

import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

الجدير بالذكر هنا، ان المجموعة customers لن يتم إنشائها بشكل فعلي حتى تقوم بإدراج مستند فيها.

إدارج مستندات Documents إلى مجموعة Collection في مونغو دي بي

لإدارج مستند إلى مجموعة نستطيع استخدام التابع insert_one الذي يقبل بارامتر dictionary يحوي بدوره اسم وقيمة المستند الذي ترغب بإدارجه ضمن المجموعة.

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

mydict = { "name": "John", "address": "Highway 37" }

x = mycol.insert_one(mydict)

يعيد التابع insert_one كائن من نوع InserOneResult الذي يحوي قيمة inserted_id تمثل قيمة معرف المستند الذي تم اضافته إلى المجموعة كماهوي مبين في المثال التالي:

mydict = { "name": "Peter", "address": "Lowstreet 27" }

x = mycol.insert_one(mydict)

print(x.inserted_id)

في المثال بالأعلى تقوم مونغو بإسناد قيمة معرف ID للمستند بشكل فريد وعشوائي, اذا رغبت بإسناد قيمة معرف للمستند ، كل ماعليك فعله هو وضع قيمة في المعجم للحقل _id .

إدراج عدة مستندات في مونغودي بي

تستطيع إدراج عدة مستندات عبر التابع insert_many الذي يقبل لائحة من المعاجم كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

mylist = [
  { "name": "Amy", "address": "Apple st 652"},
  { "name": "Hannah", "address": "Mountain 21"},
  { "name": "Michael", "address": "Valley 345"},
  { "name": "Sandy", "address": "Ocean blvd 2"},
  { "name": "Betty", "address": "Green Grass 1"},
  { "name": "Richard", "address": "Sky st 331"},
  { "name": "Susan", "address": "One way 98"},
  { "name": "Vicky", "address": "Yellow Garden 2"},
  { "name": "Ben", "address": "Park Lane 38"},
  { "name": "William", "address": "Central st 954"},
  { "name": "Chuck", "address": "Main Road 989"},
  { "name": "Viola", "address": "Sideway 1633"}
]

x = mycol.insert_many(mylist)

#print list of the _id values of the inserted documents:
print(x.inserted_ids)


إدراج مستندات في مونغو مع تحديد المعرّف الخاص بهم

كما ذكرنا في الأعلى تستطيع ان تحدد المعرّف الخاص بالمستند الذي ترغب بإدراجه في حال لا ترغب ان تقوم مونغو بتحديد المعرف بشكل تلقائي عن طريق ادراج قيمة _id للمستند كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

mylist = [
  { "_id": 1, "name": "John", "address": "Highway 37"},
  { "_id": 2, "name": "Peter", "address": "Lowstreet 27"},
  { "_id": 3, "name": "Amy", "address": "Apple st 652"},
  { "_id": 4, "name": "Hannah", "address": "Mountain 21"},
  { "_id": 5, "name": "Michael", "address": "Valley 345"},
  { "_id": 6, "name": "Sandy", "address": "Ocean blvd 2"},
  { "_id": 7, "name": "Betty", "address": "Green Grass 1"},
  { "_id": 8, "name": "Richard", "address": "Sky st 331"},
  { "_id": 9, "name": "Susan", "address": "One way 98"},
  { "_id": 10, "name": "Vicky", "address": "Yellow Garden 2"},
  { "_id": 11, "name": "Ben", "address": "Park Lane 38"},
  { "_id": 12, "name": "William", "address": "Central st 954"},
  { "_id": 13, "name": "Chuck", "address": "Main Road 989"},
  { "_id": 14, "name": "Viola", "address": "Sideway 1633"}
]

x = mycol.insert_many(mylist)

#print list of the _id values of the inserted documents:
print(x.inserted_ids)


استرجاع المستندات في مونغو دي بي

لاسترجاع مستند في مونغو نستطيع استخدام التابع find_one الذي تقوم بإعادة أول مستند:

import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]
x = mycol.find_one()
print(x)

لاسترجاع بيانات من جدول في MongoDN نستطيع استخدام التابع find الي يقوم باسترجاع جميع المستندات المطابقة. البارامتر الأول الذي يقبله التابع find هوي كائن من نوع query ، كما نستطيع ترك هذا الحقل فارغا، على سبيل المثال لاسترجاع جميع المستند كما تفعل التعليمة select * في SQL نستطيع تنفيذ مايلي:

import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]
for x in mycol.find():
  print(x)

المثال في الأعلى سيرجع جميع الحقول الخاصة بكل مستند، اما اذا أردنا استرجاع بعض الحقول  مثل الاسم فقط، نستطيع ضبط البارامتر الثاني للتابع find كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

for x in mycol.find({},{ "_id": 0, "name": 1, "address": 1 }):
  print(x)

لاحظ ان الحقول التي تحوي قيمة ١ في المعجم سيتم استرجاعها، اما الحقول التي تحوي القيمة 0 فلن يتم استرجاعها.

الاستعلامات في مونغو دي بي

الاستعلام في مونغودي بي يتم بناءه باستخدام المعاجم، حيث نقوم باختيار قيمة key الحقل الذي نريد تطبيق شرط عليه, وقيمة هذا المفتاح value هي الشرط الذي نريد تطبيقه على الحقل key

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

myquery = { "address": "Park Lane 38" }

mydoc = mycol.find(myquery)

for x in mydoc:
  print(x)

تنفيذ الاستعلام في الأعلى سيعيد المستندات التي قيمة العنوان فيها address مساوية ل Park Lane 38

تدعم مونغو إستعلامات متقدمة ايضا، مثلا لعرض المستندات التي تبدأ العناوين فيها بالحرف S او بأي حرف ابجدي بعد S مثل (T,U etc.  ) نستطيع استخدام التعبير 

myquery = { "address": { "$gt": "S" } }

حيث تشير gt الى greater than .

مايميز الاستعلامات في مونغودي بي هو دعمها للتعابير النظامية Regular Expression حيث نستطيع استرجاع مستندات بعد تطبيق قيمة تعبير نظامي على حقل فيها كمايلي

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

myquery = { "address": { "$regex": "^S" } }

mydoc = mycol.find(myquery)

for x in mydoc:
  print(x)

المثال أعلاه يعني استعادة المستندات التي يبدأ العنوان فيها بحرف S.

ترتيب النتائج Sort في مونغودي بي

في بعض الحالات، قد ترغب بترتيب النتائج التي تم استرجاعها حسب قيمة واحد من الحقول, تستطيع استخدام التابع sort لذلك، يقبل التابع sort بارامترين، البارامتر الأول هو الحقل في المستند الذي ترغب الترتيب حسبه، والبارامتر الثاني هو نوع الترتيب (١: يعني ترتيب تصاعدي، -١ يعني ترتيب تنازلي)، في المثال التالي يتم ترتيب المستندات تنازليا حسب اسم العميل:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

mydoc = mycol.find().sort("name", -1)

for x in mydoc:
  print(x)

حذف المستندات في مونغو دي بي

لحذف المستندات في مونغو، نستطيع استخدام التابع delete_one الذي يقبل بارامتر واحد هو استعلام يعيد المستندات التي نرغب بحذفها. في المثال التالي سيتم حذف اول مستند يحوي قيمة Mountain 21 كقيمة للحقل address

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]
myquery = { "address": "Mountain 21" }

mycol.delete_one(myquery)

التابع delete_many  في مونغو ديبي

لحذف عدة مستندات في مونغو ديبي, نستطيع استخدام التابع delete_many الذي سيقوم بحذف جميع المستندات التي تطابق الاستعلام query في البارامتر الممرر له، على سبيل المثال، نستطيع تمرير استعلام كتعبير نظامي ليتم حذف جميع المستندات التي تحوي عنوان يبدأ بحرف S كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

myquery = { "address": {"$regex": "^S"} }

x = mycol.delete_many(myquery)

print(x.deleted_count, " documents deleted.")

الجدير بالذكر, أن التابع delete_many يعيد قيمة عدد المستندات التي تم حذفها.

حذف جميع المستندات في المجموعة Collection في مونغو دي بي

لحذف جميع المستندات المخزنة في مجموعة فقط نقوم باستدعاء التابع delete_many بدون اي بارامتر (فلترة) كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

x = mycol.delete_many({})

print(x.deleted_count, " documents deleted.")

حذف مجموعة Collection في مونغو دي بي

لحذف مجموعة Collection في مونغو دي بي نقوم بتنفيذ التابع drop على المجموعة التي نرغب بحذفها كمايلي:

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

mycol.drop()

التابع drop يعيد القيمة true في حالة تم حذف المجموعة بنجاح أو false في حال حدوث خطأ ما (كأن يكون اسم المجموعة غير صحيح).

عرض عدد معين من المستندات Limit في مونغو ديبي

تستطيع تحديد العدد الأعظمي من النتائج التي تريد عرضها باستخدام التابع limit كمايلي

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]

myresult = mycol.find().limit(5)

#print the result:
for x in myresult:
  print(x)

في المثال في الأعلى سيتم عرض فقط ٥ مستندات.

في هذه المقالة عرضنا جميع الأوامر التي تحتاجها لتطوير تطبيقات في بايثون واستخدام قاعدة بيانات مونغو دي بي كوسط تخزين، نتمنى ان تكون قد استفدت من هذه المقالة.