Python आणि MongoDB Marathi Tutorial

MySQL मध्ये data table मध्ये, ठरलेल्या columns मध्ये बसवावा लागतो. MongoDB मध्ये data document म्हणून साठतो, जो दिसायला Python च्या dictionary सारखाच असतो.

MySQLMongoDB
DatabaseDatabase
TableCollection
RowDocument
ColumnField

उधारी रजिस्टरचे उदाहरण घ्या. एका ग्राहकाचा फोन नंबर आहे, दुसऱ्याचा नाही. कुणाचा पत्ता आहे, कुणाचा नाही. SQL मध्ये यासाठी रिकामे (NULL) columns ठेवावे लागतात. MongoDB मध्ये प्रत्येक document ला हवे तेच fields देता येतात. म्हणून data ची रचना वारंवार बदलत असेल तर MongoDB सोपे पडते.

एक प्रामाणिक मुद्दा: पैशांचे व्यवहार, अनेक tables मधले घट्ट संबंध (उदा. बँकिंग) यासाठी SQL अजूनही जास्त योग्य आहे. MongoDB प्रत्येक ठिकाणी चांगले नाही.

Setup

pip install pymongo

MongoDB दोन प्रकारे मिळते:

  1. Local: तुमच्या laptop वर MongoDB Community Server install करा.
  2. Atlas (cloud): MongoDB Atlas वर free tier (M0) मध्ये account काढा. Install काही नको.

Connect करणे

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client["kirana_db"]
customers = db["customers"]

लक्षात ठेवा: kirana_db आणि customers या ओळींनी लगेच काही तयार होत नाही. MongoDB database आणि collection तेव्हाच बनवतो जेव्हा तुम्ही पहिला document insert करता. नवीन विद्यार्थी इथेच गोंधळतात, कारण Compass मध्ये database दिसत नाही आणि त्यांना वाटते की काहीतरी चुकले.

Atlas वापरत असाल तर: password कोडमध्ये थेट लिहू नका. GitHub वर टाकला तर तो चोरीला

import os
client = MongoClient(os.environ["MONGO_URI"])

एक ग्राहक:

customers.insert_one({
    "name": "Ramesh Patil",
    "village": "Jalgaon",
    "phone": "98XXXXXXXX",
    "due": 1200
})

एकाच वेळी अनेक:

customers.insert_many([
    {"name": "Sunita More", "village": "Bhusawal", "due": 450},
    {"name": "Anil Chaudhari", "village": "Jalgaon", "due": 3000, "notes": "सणाला पैसे देतो"},
    {"name": "Kavita Pawar", "village": "Erandol", "due": 0}
])

तिसऱ्या ग्राहकाला notes field आहे, बाकीच्यांना नाही. हीच MongoDB ची लवचिकता. प्रत्येक document ला MongoDB आपोआप एक _id (ObjectId) देतो. तो unique असतो.

# सगळे
for c in customers.find():
    print(c)

# एकच (सापडला नाही तर None मिळतो)
c = customers.find_one({"name": "Ramesh Patil"})

# Jalgaon चे ग्राहक
for c in customers.find({"village": "Jalgaon"}):
    print(c["name"], c["due"])

# 1000 पेक्षा जास्त उधारी
customers.find({"due": {"$gt": 1000}})

# Jalgaon किंवा Bhusawal
customers.find({"village": {"$in": ["Jalgaon", "Bhusawal"]}})

# Jalgaon चे आणि 1000 पेक्षा जास्त उधारी
customers.find({"village": "Jalgaon", "due": {"$gt": 1000}})

# फक्त name आणि due, _id नको
customers.find({}, {"name": 1, "due": 1, "_id": 0})

# सर्वात जास्त उधारी असलेले 3 ग्राहक
customers.find().sort("due", -1).limit(3)

-1 म्हणजे मोठ्याकडून लहानाकडे, 1 म्हणजे लहानाकडून मोठ्याकडे.

मोजणे

customers.count_documents({"due": {"$gt": 0}})

# रमेशने 500 रुपये दिले, उधारी 500 ने कमी
customers.update_one(
    {"name": "Ramesh Patil"},
    {"$inc": {"due": -500}}
)

# Phone नंबर नोंदवणे
customers.update_one(
    {"name": "Sunita More"},
    {"$set": {"phone": "97XXXXXXXX"}}
)

# सगळ्यांना एक नवीन field
customers.update_many({}, {"$set": {"active": True}})

$inc ची खासियत: जुनी किंमत वाचून, गणित करून परत लिहावी लागत नाही. MongoDB ते एका पावलात करतो. दोन माणसे एकाच वेळी रजिस्टर बदलत असली तरी चूक होत नाही.

मोठी चूक: update_one मध्ये $set विसरू नका. {"due": 100} असे थेट दिले तर PyMongo error देतो. पूर्ण document बदलायचा असेल तेव्हाच replace_one वापरा.

customers.delete_one({"name": "Kavita Pawar"})
customers.delete_many({"due": 0})

delete_many({}) म्हणजे collection मधले सगळे documents गेले. Run करण्याआधी एकदा count_documents ने किती जाणार ते बघा.

ग्राहक 50 असतील तर काहीच फरक पडत नाही. 5 लाख असतील तर फरक पडतो. Index नसेल तर MongoDB प्रत्येक document तपासतो.

customers.create_index("phone", unique=True)

unique=True मुळे एकच phone नंबर दोनदा टाकता येत नाही. टाकला तर:

from pymongo.errors import DuplicateKeyError

try:
    customers.insert_one({"name": "Test", "phone": "97XXXXXXXX"})
except DuplicateKeyError:
    print("हा नंबर आधीच नोंदलेला आहे")

रजिस्टरमधला खरा प्रश्न: कोणत्या गावाकडून किती पैसे यायचे आहेत?

pipeline = [
    {"$group": {"_id": "$village", "total_due": {"$sum": "$due"}}},
    {"$sort": {"total_due": -1}}
]

for row in customers.aggregate(pipeline):
    print(row["_id"], row["total_due"])

Pipeline म्हणजे पायऱ्यांची साखळी. पहिल्या पायरीचा output दुसऱ्या पायरीचा input बनतो. SQL मधल्या GROUP BY शी याची तुलना करता येईल.

import pandas as pd

df = pd.DataFrame(list(customers.find({}, {"_id": 0})))
print(df)

find() जो cursor परत करतो, तो एकदाच वाचता येतो. म्हणून आधी list() करायचे. Cursor रिकामा आहे का ते तपासण्यासाठी find_one() वापरणे सोपे पडते.

  1. ServerSelectionTimeoutError: MongoDB चालू नसते. Local असेल तर service सुरू करा, Atlas असेल तर IP address Network Access मध्ये allow करा.
  2. _id वरून शोधताना string देणे: find_one({"_id": "65ab..."}) चालत नाही. from bson import ObjectId करून ObjectId("65ab...") द्यावे लागते.
  3. find_one ला None येतो आणि त्यावर ["name"] मागणे. आधी if c: तपासा.
  4. Password कोडमध्ये लिहून GitHub वर टाकणे.
  5. insert_many मध्ये एक चूक झाली तर बाकीचे थांबतात. याबद्दल ordered=False वाचा.

Q1. MongoDB फुकट आहे का?

Ans: Community Server पूर्णपणे फुकट आहे. Atlas वर 512 MB चे free tier आहे, शिकण्यासाठी पुरेसे. (अटी बदलू शकतात, Atlas च्या साइटवर एकदा पडताळा.)

Q2. MongoDB आधी शिकावे की SQL?

Ans: SQL आधी. Database ची मूळ कल्पना तिथे स्पष्ट होते आणि नोकरीच्या मुलाखतीत SQL जास्त विचारतात. नंतर MongoDB सोपे वाटते.

Q3. PyMongo आणि MongoDB एकच का?

Ans: नाही. MongoDB हा database आहे, PyMongo ही Python ची library जी त्याच्याशी बोलते.

Scroll to Top