پایتون و MongoDB: آشنایی با متد find و شیء query

11 آبان 1398
پایتون و MongoDB: آشنایی با متد find و شیء query

متد find و find_one

اگر یادتان باشد در پایگاه های داده ی MySQL می توانستیم با استفاده از دستور SELECT داده های خودمان را پیدا کنیم. در MongoDB دو متد به نام find و find_one داریم که دقیقا معادل دستور SELECT می باشند و برای پیدا کردن داده ها درون کالکشن استفاده می شوند. تفاوت این دو متد هم در آن است که find_one تنها اولین نتیجه را برمی گرداند (حتی اگر درخواست ما شامل چندین نتیجه شود) اما find تمام نتایج را به صورت کامل برمی گرداند. من دو مثال را برای شما آماده کرده ام تا تفاوت این دو متد را به خوبی درک کنید.

مثال اول: استفاده از متد()find_one

import pymongo

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

x mycol.find_one()

print(x)

خروجی:

{'_id': 1, 'name': 'John', 'address': 'Highway37'}

در این کد درخواست پیچیده ای وجود ندارد بلکه find_one را مستقیما روی کالکشن customers صدا زده ایم بنابراین اولین document (ردیف) از این کالکشن به ما برگردانده می شود.

مثال دوم: استفاده از متد ()find

import pymongo

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

for x in mycol.find():
  print(x)

خروجی:

{'_id': 1, 'name': 'John', 'address': 'Highway37'}
{'_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'}

اولین پارامتر متد ()find یک شیء کوئری است. در مثال بالا من از یک شیء کوئری خالی استفاده کرده ام تا تمام document های درون کالکشن را برگرداند. در واقع اگر به ()find هیچ شیء کوئری ندهید، معادل دستور * SELECT در MySQL را ایجاد کرده اید.

برگرداندن برخی از فیلدها

پارامتر دوم ()find یک شیء است که تعیین می کند چه فیلدهایی در نتایج برگشتی قرار بگیرند. این پارامتر اختیاری است و اگر چیزی به آن نداده باشید تمام فیلدها برگردانده خواهند شد. به طور مثال در کد زیر گفته ایم نام ها و آدرس ها را برگردان اما id_ ها برگردانده نشوند:

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)

خروجی:

{'name': 'John', 'address': 'Highway37'}
{'name': 'Peter', 'address': 'Lowstreet 27'}
{'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'}

در مثال قبلی گفتیم که شیء کوئری (پارامتر اول) را خالی گذاشته ایم که معادل پاس داده یک شیء خالی به find است اما از آنجایی که در مثال بالا میخواهیم پارامتر دوم را نیز پاس بدهیم، حتما باید شیء خالی را به Find پاس بدهیم تا مشخص شود شیء بعدی پارامتر دوم است.

بررسی یک استثناء مهم: شما اجازه ندارید که در یک شیء مقادیر 0 و 1 را مشخص کنید؛ در واقع اگر به یک فیلد مقدار 0 بدهید، بقیه ی فیلدها مقدار 1 می گیرند. اگر به مثال بالا دقت کنید برای پارامتر دوم شیء زیر را پاس داده ایم:

"_id"0"name"1"address"1 }

حتما برایتان سوال شده است که این شیء با چیزی که گفتیم جور در نمی آید. ما گفتیم در یک شیء نمی توانیم هم مقادیر 0 و هم مقادیر 1 را مشخص کنیم پس چطور در شیء بالا چنین کاری انجام داده ایم؟ اگر یکی از فیلد ها id_ باشد با یک استثناء طرف هستیم و استثنائا می توانیم هر دو مقدار 0 و 1 را مشخص کنیم.

بیایید برای درک بهتر یک مثال دیگر را نیز بررسی کنیم. در مثال زیر میخواهیم فیلد address در نتایج برگشتی نباشد:

import pymongo

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

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

خروجی:

{'_id': 1, 'name': 'John'}
{'_id': 2, 'name': 'Peter'}
{'_id': 3, 'name': 'Amy'}
{'_id': 4, 'name': 'Hannah'}
{'_id': 5, 'name': 'Michael'}
{'_id': 6, 'name': 'Sandy'}
{'_id': 7, 'name': 'Betty'}
{'_id': 8, 'name': 'Richard'}
{'_id': 9, 'name': 'Susan'}
{'_id': 10, 'name': 'Vicky'}
{'_id': 11, 'name': 'Ben'}
{'_id': 12, 'name': 'William'}
{'_id': 13, 'name': 'Chuck'}
{'_id': 14, 'name': 'Viola'}

همانطور که می بینید تنها مقدار address در شیء پارامتر بالا 0 قرار داده شده است و موارد دیگر به صورت خودکار 1 را دریافت خواهند کرد. در واقع اگر کد بالا را به صورت زیر بنویسیم با خطا مواجه خواهیم شد:

import pymongo

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

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

این کد باعث ایجاد خطا و توقف برنامه ی شما خواهد شد.

آشنایی با شیء کوئری

در مثال های بالا شیء کوئری را خالی گذاشتیم اما معمولا برنامه های ما اینطور نخواهند بود. شما می توانید با استفاده از شیء کوئری نتایج خود را فیلتر کنید. همانطور که می دانید شیء کوئری پارامتر اول متد ()find است. به طور مثال در کد زیر document هایی را برمی گردانیم که آدرس آن ها Park Lane 38 باشد:

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)

خروجی:

{'_id': 11, 'name': 'Ben', 'address': 'Park Lane 38'}

البته این یک کوئری بسیار ساده است. ما می توانیم با استفاده از modifier ها شیء کوئری خود را بسیار پیشرفته تر کنیم؛ به طور مثال اگر بخواهیم document هایی را برگردانیم که در آن ها address با حرف S یا حروف بعد از S (در الفبای انگلیسی) شروع شده باشد می گوییم {"gt": "S$"} برای مثال:

import pymongo

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

#address greater than S:
myquery = { "address": {"$gt": "S"} }

mydoc = mycol.find(myquery)

for x in mydoc:
  print(x)

خروجی:

{'_id': 5, 'name': 'Michael', 'address': 'Valley 345'}
{'_id': 8, 'name': 'Richard', 'address': 'Sky st 331'}
{'_id': 10, 'name': 'Vicky', 'address': 'Yellow Garden 2'}
{'_id': 14, 'name': 'Viola', 'address': 'Sideway 1633'}

شما حتی می توانید از عبارات با قاعده (regular expressions) استفاده کنید. به طور مثال اگر بخواهیم document هایی را برگردانیم که address آن ها با حرف S شروع شده باشد می گوییم {"regex": "^S$"}. به کد زیر توجه کنید:

import pymongo

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

#address starts with S:
myquery = { "address": { "$regex": "^S" } }

mydoc = mycol.find(myquery)

for x in mydoc:
  print(x)

خروجی:

{'_id': 10, 'name': 'Richard', 'address': 'Sky st 331'}
{'_id': 14, 'name': 'Viola', 'address': 'Sideway 1633'}

دنیای regular expression ها دنیای بسیار بزرگی است که دوره ی خودش را می طلبد و نمی توانیم در همین مقاله آن را بررسی کنیم اما طرز استفاده ی آن را به شما نشان دادیم و اگر کار با regular expression را یاد داشته باشید، به راحتی می توانید از هر دستوری در آن استفاده کنید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری از مقدماتی تا پیشرفته با پایتون توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.