TinyDB একটি হালকা-ওজনের NoSQL ডাটাবেস, যা JSON ফাইল ব্যবহার করে ডেটা সংরক্ষণ করে। TinyDB সহজ, ছোট স্কেল ডেটাবেস ম্যানেজমেন্টের জন্য উপযুক্ত, তবে আপনি Advanced Query Techniques ব্যবহার করে এর ক্ষমতাগুলি আরও বাড়াতে পারেন। এখানে কিছু উন্নত কোয়েরি কৌশল এবং কৌশল রয়েছে যা TinyDB এর সাথে কাজ করতে পারেন:
১. Logical Operators (AND, OR, NOT)
TinyDB তে আপনি AND, OR, এবং NOT অপারেটর ব্যবহার করে যৌক্তিকভাবে একাধিক শর্ত একত্রিত করতে পারেন।
AND অপারেটর
& অপারেটর ব্যবহার করে আপনি একাধিক শর্ত যোগ করতে পারেন (যেমন, বয়স এবং শহর)।
from tinydb import TinyDB, Query
# TinyDB ইনস্ট্যান্স তৈরি
db = TinyDB('db.json')
# ডেটা ইনসার্ট
db.insert_multiple([
{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'},
{'name': 'Karim', 'age': 30, 'city': 'Chittagong'},
{'name': 'Aziz', 'age': 35, 'city': 'Dhaka'},
{'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}
])
# AND অপারেটর ব্যবহার
User = Query()
result = db.search((User.age > 25) & (User.city == 'Dhaka'))
print(result)
# আউটপুট:
# [{'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}]
OR অপারেটর
| অপারেটর ব্যবহার করে একাধিক শর্তের মধ্যে OR যুক্ত করা যায়।
# OR অপারেটর ব্যবহার
result = db.search((User.age < 30) | (User.city == 'Chittagong'))
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'}, {'name': 'Karim', 'age': 30, 'city': 'Chittagong'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}]
NOT অপারেটর
~ অপারেটর ব্যবহার করে শর্তের বিপরীত (NOT) করতে পারেন।
# NOT অপারেটর ব্যবহার
result = db.search(~(User.city == 'Dhaka'))
print(result)
# আউটপুট:
# [{'name': 'Karim', 'age': 30, 'city': 'Chittagong'}]
২. Regex Matching (Regular Expressions)
TinyDB এ matches() ফাংশন ব্যবহার করে আপনি রেগুলার এক্সপ্রেশন (Regex) এর মাধ্যমে ডেটার সঙ্গে মিলে যাওয়া কন্ডিশন চেক করতে পারেন।
# Regular expression (Regex) দিয়ে নামের মধ্যে 'i' অক্ষর খুঁজে বের করা
result = db.search(User.name.matches('.*i.*'))
print(result)
# আউটপুট:
# [{'name': 'Karim', 'age': 30, 'city': 'Chittagong'}, {'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}]
৩. Range Queries (বয়সের মধ্যে মান অনুসন্ধান)
TinyDB তে Range Queries ব্যবহার করে একটি নির্দিষ্ট পরিসরে ডেটা খুঁজে বের করা সম্ভব। যেমন, বয়স ২৫ থেকে ৩৫ এর মধ্যে খুঁজে বের করা।
# বয়স ২৫ থেকে ৩৫ এর মধ্যে খুঁজে বের করা
result = db.search((User.age >= 25) & (User.age <= 35))
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}, {'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}]
৪. Sorting Results
TinyDB তে আপনি order_by() ফাংশন ব্যবহার করে ডেটা সাজাতে পারেন।
# বয়স অনুযায়ী সাজানো
result = db.all()
result.sort(key=lambda x: x['age']) # বয়স অনুসারে সাজানো
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}, {'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}, {'name': 'Karim', 'age': 30, 'city': 'Chittagong'}]
৫. Limiting Results (Pagination)
TinyDB তে একটি limit() ফাংশন নেই, তবে আপনি Python এর list slicing ব্যবহার করে ফলাফল সীমাবদ্ধ করতে পারেন, যেমন পেইজিনেশন।
# প্রথম 2টি ফলাফল
result = db.all()[:2]
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'}, {'name': 'Karim', 'age': 30, 'city': 'Chittagong'}]
৬. Complex Query Conditions with Functions
TinyDB তে আপনি complex conditions তৈরি করতে ম্যানুয়াল ফাংশন ব্যবহার করতে পারেন।
# একটি ফাংশন তৈরি করা যা ডেটা চেক করবে
def is_eligible_for_offer(data):
return data['age'] >= 25 and data['city'] == 'Dhaka'
# Query করে 'Dhaka' শহরের ২৫ এর বেশি বয়সী লোক খুঁজে বের করা
result = db.search(User.where(is_eligible_for_offer))
print(result)
# আউটপুট:
# [{'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}]
৭. Using in for Multiple Values Matching
TinyDB তে in অপারেটর ব্যবহার করে আপনি একাধিক মানের মধ্যে মেলানো শর্ত নির্ধারণ করতে পারেন।
# শহরগুলোর মধ্যে যেগুলো 'Dhaka' বা 'Chittagong' এর মধ্যে পড়ে
result = db.search(User.city.in(['Dhaka', 'Chittagong']))
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'city': 'Dhaka'}, {'name': 'Karim', 'age': 30, 'city': 'Chittagong'}, {'name': 'Aziz', 'age': 35, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 28, 'city': 'Dhaka'}]
৮. Nested Data Querying
TinyDB এ nested ডেটা, যেমন একটি লিস্টের মধ্যে অবজেক্ট, এর সাথে কাজ করার জন্য আপনি where() এবং matches() ফাংশন ব্যবহার করতে পারেন।
# Nested ডেটা অনুসন্ধান
db.insert({'name': 'Rahim', 'age': 25, 'addresses': [{'city': 'Dhaka', 'street': 'Street 1'}, {'city': 'Chittagong', 'street': 'Street 2'}]})
# শহর 'Dhaka' থাকার শর্তে nested লিস্টের মধ্যে অনুসন্ধান
result = db.search(User.addresses.any({'city': 'Dhaka'}))
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 25, 'addresses': [{'city': 'Dhaka', 'street': 'Street 1'}, {'city': 'Chittagong', 'street': 'Street 2'}]}]
সারাংশ
TinyDB তে Advanced Query Techniques ব্যবহার করে আপনি ডেটা অনুসন্ধান এবং বিশ্লেষণ আরও কার্যকরী এবং কার্যক্ষম করতে পারেন। Logical Operators, Regex Matching, Range Queries, Sorting, Pagination, এবং Nested Data Querying এর মতো বিভিন্ন কৌশল আপনাকে ডেটার উপর শক্তিশালী এবং নমনীয় কোয়েরি চালাতে সহায়তা করবে।
Subqueries এবং Nested Queries হল SQL এর গুরুত্বপূর্ণ ধারণা যা একটি কোয়েরি (Query) এর ভিতরে অন্য কোয়েরি ব্যবহার করার পদ্ধতি। এগুলো সাধারণত বড় বা জটিল ডেটাবেস অপারেশনগুলিকে সহজে এবং কার্যকরভাবে সমাধান করতে ব্যবহৃত হয়।
Subqueries (সাবকোয়েরি)
Subquery হল একটি কোয়েরি যা অন্য কোয়েরির ভিতরে থাকে। এটি প্রধান কোয়েরি (Outer Query) এর ফলাফল নির্ধারণ করতে সাহায্য করে এবং সাধারণত WHERE, FROM, অথবা SELECT ক্লজের মধ্যে থাকে। সাবকোয়েরি সাধারণত একটি মান বা একাধিক মান ফেরত দেয়।
Subquery এর ধরন
- Scalar Subquery: এটি একক মান (Single Value) ফেরত দেয়।
- Multi-row Subquery: এটি একাধিক রো ফেরত দেয়।
- Correlated Subquery: এটি বাহ্যিক কোয়েরির প্রতিটি রো অনুসারে সাবকোয়েরি চালায়।
- Non-correlated Subquery: এটি বাহ্যিক কোয়েরি থেকে সম্পূর্ণ স্বাধীন, একবার চালানো হলে সব রো এর জন্য একই ফলাফল দেয়।
Subquery Example (Scalar Subquery):
SELECT name, age
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE department_name = 'Sales'
);
এই কোয়েরি Sales বিভাগের সমস্ত কর্মচারীর নাম এবং বয়স ফেরত দেবে। এখানে সাবকোয়েরি Sales বিভাগের department_id নির্ধারণ করে, এবং প্রধান কোয়েরি সেই department_id সহ কর্মচারীদের তথ্য বের করে।
Subquery Example (Multi-row Subquery):
SELECT name, age
FROM employees
WHERE department_id IN (
SELECT department_id
FROM departments
WHERE location = 'New York'
);
এখানে সাবকোয়েরি New York অবস্থানে থাকা সমস্ত বিভাগগুলির department_id বের করে এবং প্রধান কোয়েরি তাদের বিভাগগুলির কর্মচারীদের তথ্য ফিরিয়ে দেয়।
Correlated Subquery:
SELECT e.name, e.age
FROM employees e
WHERE e.salary > (
SELECT AVG(salary)
FROM employees
WHERE department_id = e.department_id
);
এটি একটি correlated subquery, যেখানে সাবকোয়েরি বাহ্যিক কোয়েরির (Main Query) প্রতিটি রো (এখানে প্রতিটি কর্মচারী) এর জন্য সম্পাদিত হয়। প্রতিটি কর্মচারী তার বিভাগের গড় বেতন থেকে বেশি বেতন পাচ্ছে কিনা তা পরীক্ষা করা হচ্ছে।
Nested Queries (নেস্টেড কোয়েরি)
Nested Query হল একাধিক কোয়েরি (একটি কোয়েরি আরেকটির ভিতরে) যা একে অপরের সাথে সম্পর্কিত। নেস্টেড কোয়েরি সাধারণত একাধিক স্তরের সাবকোয়েরি নিয়ে গঠিত এবং একাধিক স্তরের ডেটা বিশ্লেষণে ব্যবহৃত হয়।
একটি Nested Query সাধারণত দুটি বা তার বেশি সাবকোয়েরি ব্যবহার করে যা একটি একক বৃহৎ কোয়েরিতে একত্রিত হয়। এটি Complex Queries তৈরি করতে সহায়ক।
Nested Query Example:
SELECT name, age
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE location = 'New York'
LIMIT 1
);
এটি একটি nested query। বাহ্যিক কোয়েরি employees টেবিল থেকে কর্মচারীদের নাম এবং বয়স বের করে, এবং ভিতরের কোয়েরি departments টেবিল থেকে New York অবস্থানে থাকা বিভাগের department_id বের করে।
Multiple Nested Queries Example:
SELECT name, salary
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE department_name = (
SELECT department_name
FROM departments
WHERE location = 'New York'
LIMIT 1
)
);
এখানে তিনটি স্তরের nested queries আছে। প্রথমে New York অবস্থানে থাকা বিভাগের নাম বের করা হচ্ছে, তারপরে সেই বিভাগের department_id এবং শেষ পর্যন্ত সেই বিভাগে কাজ করা কর্মচারীদের নাম এবং বেতন বের করা হচ্ছে।
Subqueries vs Nested Queries
- Subqueries সাধারণত একটি কোয়েরির ভিতরে অন্য একটি কোয়েরি থাকে এবং এটি শুধুমাত্র একটি স্তরের কোয়েরি হতে পারে।
- Nested Queries একাধিক স্তরের সাবকোয়েরি নিয়ে গঠিত, যেখানে একটি কোয়েরি অন্য কোয়েরির ভিতরে থাকতে পারে, এবং এটি আরও জটিল ডেটাবেস অপারেশন সম্পাদন করতে ব্যবহৃত হয়।
সারাংশ
- Subqueries এবং Nested Queries ডেটাবেসে জটিল তথ্য অনুসন্ধান এবং ডেটা বিশ্লেষণ সহজ করে।
- Subqueries সাধারণত WHERE, FROM, অথবা SELECT ক্লজের মধ্যে থাকে, যেখানে Nested Queries একাধিক স্তরের সাবকোয়েরি নিয়ে গঠিত।
- এগুলি SQL কোয়েরি অপ্টিমাইজেশন এবং ডেটা ম্যানিপুলেশন এর জন্য শক্তিশালী টুল।
TinyDB একটি হালকা-ওজনের NoSQL ডাটাবেস যা মূলত JSON ফাইল ব্যবহার করে ডেটা সংরক্ষণ করে। এটি রিলেশনাল ডাটাবেসের মতো GROUP BY বা Aggregation Functions (যেমন SUM, COUNT, AVG) সরাসরি সমর্থন করে না। তবে, TinyDB এর মধ্যে Aggregation ফাংশনগুলি বাস্তবায়ন করতে আপনি কিছু কোড লজিক ব্যবহার করে এটি অর্জন করতে পারেন।
নিচে, SUM, COUNT, এবং AVG ফাংশন ব্যবহার করার জন্য কিছু উদাহরণ দেওয়া হয়েছে, যা TinyDB ডেটাবেসে অ্যাগ্রিগেটেড ডেটা রিটার্ন করতে সাহায্য করবে।
১. SUM (মোট যোগফল)
SUM ফাংশন সাধারণত একটি নির্দিষ্ট ক্ষেত্রের সব মানের যোগফল বের করতে ব্যবহৃত হয়। TinyDB তে SUM ফাংশন ব্যবহার করতে, আপনাকে কোডে এটি manually (হাতে) হিসাব করতে হবে।
উদাহরণ: SUM ফাংশন ব্যবহার
from tinydb import TinyDB, Query
# ডাটাবেস তৈরি
db = TinyDB('db.json')
# ডেটা ইনসার্ট করা
db.insert({'name': 'Rahim', 'age': 25, 'salary': 3000})
db.insert({'name': 'Karim', 'age': 30, 'salary': 4000})
db.insert({'name': 'Aziz', 'age': 28, 'salary': 5000})
# SUM ফাংশন: মোট salary যোগফল বের করা
total_salary = sum(item['salary'] for item in db.all())
print(f"Total Salary: {total_salary}")
আউটপুট:
Total Salary: 12000
এখানে, salary ক্ষেত্রের সমস্ত মান যোগ করে মোট 12000 ফলাফল পাওয়া যায়।
২. COUNT (গণনা)
COUNT ফাংশন ব্যবহার করে একটি নির্দিষ্ট শর্তের ভিত্তিতে ডেটার সংখ্যা বের করা যায়। TinyDB তে COUNT ফাংশন তৈরি করতে, আপনি len() ফাংশন ব্যবহার করতে পারেন যা ডেটা তালিকায় কতটি রেকর্ড আছে তা গণনা করবে।
উদাহরণ: COUNT ফাংশন ব্যবহার
# COUNT ফাংশন: কতটি ডেটা ইনসার্ট করা হয়েছে
count = len(db.all())
print(f"Total Records: {count}")
আউটপুট:
Total Records: 3
এখানে, db.all() ফাংশন ডাটাবেসের সমস্ত রেকর্ড ফিরিয়ে দেয় এবং len() ফাংশন মোট রেকর্ডের সংখ্যা গণনা করে।
৩. AVG (গড় মান)
AVG ফাংশন সাধারণত একটি নির্দিষ্ট ক্ষেত্রের গড় মান বের করতে ব্যবহৃত হয়। TinyDB তে গড় বের করতে, আমরা SUM এবং COUNT ব্যবহার করে গড় হিসাব করতে পারি।
উদাহরণ: AVG ফাংশন ব্যবহার
# AVG ফাংশন: গড় salary বের করা
avg_salary = total_salary / count # total_salary এবং count আগেই হিসাব করা হয়েছে
print(f"Average Salary: {avg_salary}")
আউটপুট:
Average Salary: 4000.0
এখানে, গড় বের করতে SUM এবং COUNT এর মান ব্যবহার করে গড় salary বের করা হয়েছে।
৪. শর্তযুক্ত Aggregation
এছাড়াও, আপনি শর্ত দিয়ে SUM, COUNT, এবং AVG গণনা করতে পারেন। যেমন, যদি আপনি শুধুমাত্র বিশেষ বয়সের কর্মীদের হিসাব করতে চান, তাহলে আপনি একটি query ব্যবহার করে নির্দিষ্ট শর্ত অনুসারে গণনা করতে পারেন।
উদাহরণ: শর্তযুক্ত COUNT, SUM, এবং AVG ফাংশন
# বয়স ৩০ এর বেশি এমন কর্মীদের salary এর গড় বের করা
User = Query()
filtered_data = [item['salary'] for item in db.search(User.age > 30)]
# COUNT, SUM, AVG
count_above_30 = len(filtered_data)
sum_above_30 = sum(filtered_data)
avg_above_30 = sum_above_30 / count_above_30 if count_above_30 > 0 else 0
print(f"Total Count (age > 30): {count_above_30}")
print(f"Total Salary (age > 30): {sum_above_30}")
print(f"Average Salary (age > 30): {avg_above_30}")
আউটপুট:
Total Count (age > 30): 1
Total Salary (age > 30): 4000
Average Salary (age > 30): 4000.0
এখানে, বয়স ৩০ এর বেশি এমন কর্মীদের জন্য আমরা COUNT, SUM, এবং AVG হিসাব করেছি।
সারাংশ
TinyDB তে Aggregation Functions যেমন SUM, COUNT, এবং AVG সরাসরি সমর্থন না করলেও, আপনি Python এর built-in ফাংশন ব্যবহার করে এই ফাংশনগুলো সহজেই ইমপ্লিমেন্ট করতে পারেন। ডেটাবেস থেকে প্রয়োজনীয় মান বের করে, আপনি উপরের মতো manual aggregation করতে পারেন।
TinyDB হল একটি হালকা-ওজনের NoSQL ডাটাবেস যা JSON ফাইলের মাধ্যমে ডেটা সংরক্ষণ করে। এটি একটি সহজ এবং কার্যকর ডাটাবেস, তবে কিছু উন্নত Filtering এবং Sorting কৌশল ব্যবহার করে ডেটা অনুসন্ধান এবং সংগঠিত করা যায়। TinyDB তে Advanced Filtering এবং Sorting এর মাধ্যমে আপনি ডেটা সঠিকভাবে এবং দ্রুত অনুসন্ধান ও সাজাতে পারবেন।
TinyDB তে Filtering এবং Sorting করার জন্য Query এবং search() মেথড ব্যবহার করা হয়। এই পোস্টে আমরা Advanced Filtering এবং Sorting কৌশল নিয়ে আলোচনা করব।
Advanced Filtering Techniques
TinyDB তে Advanced Filtering ব্যবহার করতে হলে, Query ক্লাসের সাহায্যে আপনি বিভিন্ন শর্ত এবং যুক্তি ব্যবহার করতে পারেন। এতে & (AND), | (OR), ~ (NOT), এবং matches() (Regex Matching) ব্যবহার করে আরও জটিল শর্ত তৈরি করা যায়।
১. Multiple Conditions (Multiple Shorthand Filtering)
TinyDB তে একাধিক শর্তের ভিত্তিতে ডেটা ফিল্টার করতে & (AND), | (OR) এবং ~ (NOT) অপারেটর ব্যবহার করা যায়।
from tinydb import TinyDB, Query
# ডাটাবেস তৈরি
db = TinyDB('db.json')
# ডেটা ইনসার্ট করা
db.insert({'name': 'Aziz', 'age': 30, 'city': 'Dhaka'})
db.insert({'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'})
db.insert({'name': 'Rahim', 'age': 35, 'city': 'Dhaka'})
User = Query()
# Multiple Conditions: age 30 এর বেশি এবং city 'Dhaka'
result = db.search((User.age > 30) & (User.city == 'Dhaka'))
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}]
এখানে & অপারেটরের মাধ্যমে দুটি শর্ত একসঙ্গে যোগ করা হয়েছে।
২. OR Condition (অথবা শর্ত)
| অপারেটরের মাধ্যমে একাধিক শর্তের মধ্যে OR যুক্ত করা যায়, অর্থাৎ দুটি শর্তের যেকোনো একটির পূর্ণতা হলেই ডেটা ফিরিয়ে দিবে।
# OR Condition: city 'Dhaka' অথবা age 30 এর বেশি
result = db.search((User.city == 'Dhaka') | (User.age > 30))
print(result)
# আউটপুট:
# [{'name': 'Aziz', 'age': 30, 'city': 'Dhaka'}, {'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}]
এখানে | অপারেটরের মাধ্যমে দুটি শর্তের মধ্যে OR যুক্ত করা হয়েছে, তাই Dhaka শহর বা age > 30 এর যেকোনো একটি শর্ত পূর্ণ হলেই ডেটা ফেরত আসবে।
৩. NOT Condition (মোট শর্তের বিপরীত)
~ অপারেটর ব্যবহার করে NOT শর্ত তৈরি করা যায়, যা কোনো শর্তের বিপরীত ফলাফল প্রদান করে।
# NOT Condition: city 'Dhaka' নয় এমন ডেটা
result = db.search(~(User.city == 'Dhaka'))
print(result)
# আউটপুট:
# [{'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'}]
এখানে ~ অপারেটর city == 'Dhaka' শর্তের বিপরীত কার্যকর করেছে, ফলে 'Dhaka' শহরের বাইরে থাকা ডেটা ফিরে এসেছে।
৪. Regular Expression (Regex Matching)
TinyDB তে আপনি matches() মেথড ব্যবহার করে স্ট্রিং ক্ষেত্রের মধ্যে রেগুলার এক্সপ্রেশন (Regex) অনুসন্ধান করতে পারেন।
# Regex Matching: নামের মধ্যে 'e' অক্ষর আছে এমন ডেটা
result = db.search(User.name.matches('.*e.*'))
print(result)
# আউটপুট:
# [{'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'}, {'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}]
এখানে matches('.*e.*') রেগুলার এক্সপ্রেশন ব্যবহার করে e অক্ষর থাকা সমস্ত নাম ফিল্টার করা হয়েছে।
Advanced Sorting Techniques
TinyDB তে Sorting করা যেতে পারে order_by() মেথডের মাধ্যমে। আপনি একটি বা একাধিক ক্ষেত্রের ভিত্তিতে ডেটা সাজাতে পারেন।
১. Single Field Sorting
# Age এর ভিত্তিতে ascending (ছোট থেকে বড়) সাজানো
result = db.all()
result.sort(key=lambda x: x['age'])
print(result)
# আউটপুট:
# [{'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'}, {'name': 'Aziz', 'age': 30, 'city': 'Dhaka'}, {'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}]
এখানে sort() মেথড ব্যবহার করে age ফিল্ডের উপর ascending (ছোট থেকে বড়) সাজানো হয়েছে।
২. Descending Sorting
ডেটা descending (বড় থেকে ছোট) সাজানোর জন্য, আপনি reverse=True ব্যবহার করতে পারেন।
# Age এর ভিত্তিতে descending (বড় থেকে ছোট) সাজানো
result = db.all()
result.sort(key=lambda x: x['age'], reverse=True)
print(result)
# আউটপুট:
# [{'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}, {'name': 'Aziz', 'age': 30, 'city': 'Dhaka'}, {'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'}]
এখানে reverse=True যুক্ত করার মাধ্যমে age ফিল্ডের উপর descending সাজানো হয়েছে।
৩. Multiple Field Sorting
একাধিক ফিল্ডের ভিত্তিতে ডেটা সাজানো যেতে পারে। প্রথমে একটি ফিল্ডের উপর সাজানোর পর, দ্বিতীয় ফিল্ডের উপর সাজানো হবে।
# Age এর ভিত্তিতে ascending এবং নামের ভিত্তিতে alphabetical sorting
result = db.all()
result.sort(key=lambda x: (x['age'], x['name']))
print(result)
# আউটপুট:
# [{'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'}, {'name': 'Aziz', 'age': 30, 'city': 'Dhaka'}, {'name': 'Rahim', 'age': 35, 'city': 'Dhaka'}]
এখানে age ফিল্ডের উপর প্রথমে ascending সাজানো হয়েছে এবং এরপর name ফিল্ডের উপর সাজানো হয়েছে।
সারাংশ
TinyDB তে Advanced Filtering এবং Sorting কৌশল ব্যবহার করে ডেটা অনুসন্ধান এবং সাজানো যায় খুব সহজে। আপনি Query ক্লাসের মাধ্যমে জটিল শর্ত তৈরি করতে পারেন এবং search() মেথড ব্যবহার করে ডেটা ফিল্টার করতে পারেন। একইভাবে, Sorting এর জন্য sort() মেথড ব্যবহার করা হয়, যেখানে আপনি একাধিক ক্ষেত্রের ভিত্তিতে ডেটা সাজাতে পারেন। এই কৌশলগুলো TinyDB তে ডেটা পরিচালনাকে আরও সহজ এবং কার্যকরী করে তোলে।
TinyDB একটি NoSQL ডাটাবেস যা সাধারণত ছোট স্কেল অ্যাপ্লিকেশনগুলির জন্য ব্যবহৃত হয় এবং ফাইল সিস্টেমে JSON ফাইল হিসেবে ডেটা সংরক্ষণ করে। তবে, যখন বড় ডেটাসেট বা জটিল কোয়েরি গুলির সঙ্গ নিয়ে কাজ করা হয়, তখন Query Optimization এবং Complex Query Execution অত্যন্ত গুরুত্বপূর্ণ হয়ে ওঠে।
TinyDB তে বড় বা জটিল কোয়েরি কার্যকরভাবে চালানোর জন্য কিছু Optimization techniques রয়েছে, যদিও এটি বড় স্কেল ডাটাবেসের জন্য ডিজাইন করা হয়নি। তারপরও, আপনি কিছু কৌশল ব্যবহার করে কোয়েরি পারফরম্যান্স উন্নত করতে পারেন।
Query Optimization
TinyDB তে কোয়েরি অপ্টিমাইজেশন সাধারণত নিম্নলিখিত পদ্ধতিগুলির মাধ্যমে করা হয়:
১. Indexing (ইনডেক্সিং)
TinyDB ডেটাবেসে ইনডেক্সিং ডেটা রিট্রাইভাল প্রক্রিয়া দ্রুত করতে সাহায্য করে। আপনি যদি কোনো নির্দিষ্ট ফিল্ডে প্রায়ই অনুসন্ধান করেন, তবে তা ইনডেক্সিং করার মাধ্যমে দ্রুত ফলাফল পেতে পারেন।
উদাহরণ: ইনডেক্স ব্যবহার
from tinydb import TinyDB, Query
# ডেটাবেস তৈরি
db = TinyDB('db.json')
# ডেটা ইনসার্ট করা
db.insert({'name': 'Aziz', 'age': 30, 'city': 'Dhaka'})
db.insert({'name': 'Mehedi', 'age': 25, 'city': 'Chittagong'})
db.insert({'name': 'Rahim', 'age': 40, 'city': 'Dhaka'})
# কোয়েরি অপ্টিমাইজেশন: নামের উপর অনুসন্ধান
User = Query()
result = db.search(User.city == 'Dhaka') # ইনডেক্স করা ফিল্ডে অনুসন্ধান
print(result)
এখানে, city ফিল্ডে অনুসন্ধান করলেই এটি ডিফল্ট ইনডেক্সিং সিস্টেম ব্যবহার করে দ্রুত ফলাফল দেবে।
২. Query Complexity কমানো
ডেটা ফিল্টার এবং Query অপারেশনগুলির জটিলতা কমানো সম্ভব হলে কোয়েরি দ্রুত কাজ করবে। একটি বড় ডেটাবেসের জন্য, অনেকগুলো nested বা complex শর্তের মধ্যে কোয়েরি চালানোর পরিবর্তে আপনি step-by-step বা filtered কোয়েরি ব্যবহার করতে পারেন।
উদাহরণ: সরল কোয়েরি
# বড় কোয়েরির পরিবর্তে ছোট ছোট কোয়েরি ব্যবহার করা
result = db.search(User.city == 'Dhaka')
result = [item for item in result if item['age'] > 30]
print(result)
এই কোডে প্রথমে city অনুসন্ধান করা হচ্ছে, তারপর age ফিল্টার করা হচ্ছে। এর ফলে কোয়েরি পরিচালনা অনেক সহজ হয় এবং performance বাড়ে।
৩. Avoiding Full Table Scans (পূর্ণ টেবিল স্ক্যান এড়ানো)
বড় ডেটাসেটে Full Table Scan (যেখানে পুরো ডেটাবেস স্ক্যান করতে হয়) পরিহার করা উচিত। এর পরিবর্তে indexed fields বা small chunks এ ডেটা পরিচালনা করা উচিত।
উদাহরণ: Indexed Field এ Query Execution
# city ফিল্ড ইনডেক্স করা এবং অনুসন্ধান করা
User = Query()
result = db.search(User.city == 'Dhaka') # city একটি ইনডেক্স করা ফিল্ড
print(result)
এখানে city ফিল্ডটি ইনডেক্স করা হয়েছে, যার ফলে এটি দ্রুত অনুসন্ধান করতে সাহায্য করবে।
Complex Query Execution
Complex Queries যখন অনেক শর্ত থাকে এবং একাধিক অপারেশন করতে হয়, তখন কিছু কৌশল অনুসরণ করতে হবে যাতে কোয়েরি আরও কার্যকরী হয়।
১. Nested Queries (নেস্টেড কোয়েরি)
TinyDB তে, আপনি Nested Queries ব্যবহার করে একাধিক শর্ত দিয়ে কোয়েরি তৈরি করতে পারেন। তবে অনেকটা লজিক্যাল OR বা AND অপারেটরের মাধ্যমে একাধিক শর্তযুক্ত কোয়েরি তৈরি করুন।
উদাহরণ: Nested Query Execution
# Complex query with multiple conditions
result = db.search((User.city == 'Dhaka') & (User.age > 30))
print(result)
এখানে, city এবং age দুটি শর্ত একই সাথে যাচাই করা হচ্ছে। এই কোয়েরি দ্রুত কার্যকর হবে কারণ এটি indexed fields ব্যবহার করছে।
২. Batch Operations (ব্যাচ অপারেশন)
একাধিক Insert, Update, বা Delete অপারেশন একসাথে চালানোর মাধ্যমে batch operations কোয়েরির execution time কমিয়ে দেয়।
উদাহরণ: Batch Insert
# Batch Insert
db.insert_multiple([
{'name': 'Karim', 'age': 30, 'city': 'Dhaka'},
{'name': 'Salim', 'age': 40, 'city': 'Chittagong'},
{'name': 'Sami', 'age': 20, 'city': 'Dhaka'}
])
এখানে, একসাথে অনেকগুলো Insert অপারেশন করা হচ্ছে, যা একযোগে ডেটাবেসে যুক্ত হবে এবং কর্মক্ষমতা বাড়াবে।
৩. Using Caching for Repeated Queries (পুনরাবৃত্তি কোয়েরির জন্য ক্যাশিং)
যদি আপনি একাধিক কোয়েরি করতে থাকেন যা প্রায় একই ধরনের, তাহলে ক্যাশিং ব্যবহার করতে পারেন যাতে প্রতিবার ডেটাবেস থেকে ডেটা না পড়তে হয়।
উদাহরণ: Simple Caching Example
cache = {} # Cache initialization
def get_user_data(city):
if city in cache:
return cache[city]
result = db.search(User.city == city)
cache[city] = result # Cache the result
return result
# First query will hit the database
print(get_user_data('Dhaka'))
# Subsequent queries will use the cached result
print(get_user_data('Dhaka'))
এখানে, ডেটা ক্যাশিং করা হয়েছে যাতে duplicate queries চালানোর সময় performance উন্নত হয়।
৪. Using Aggregation and Grouping
যদিও TinyDB তে grouping বা aggregation এর মত শক্তিশালী ফিচারগুলি সরাসরি নেই, তবে আপনি filter করে এবং পরে Python এর মধ্যে গ্রুপিং বা ম্যাপিং করতে পারেন।
উদাহরণ: Manually Aggregating Data
# Manually aggregate data based on city
result = db.all()
grouped = {}
for item in result:
city = item['city']
if city not in grouped:
grouped[city] = []
grouped[city].append(item)
print(grouped)
এখানে, grouping ও aggregation ব্যবহার করে ডেটা আউটপুট প্রস্তুত করা হয়েছে, যা সাধারণ SQL এর মতো কাজ করে।
সারাংশ
TinyDB তে Query Optimization এবং Complex Query Execution এর জন্য কয়েকটি কৌশল রয়েছে:
- Indexing ব্যবহার করে ডেটার দ্রুত অনুসন্ধান করা।
- Query Complexity কমানো, যেমন ছোট কোয়েরি ব্যবহার করা।
- Avoid Full Table Scans: বড় ডেটাসেটে টেবিল স্ক্যান কমানো।
- Nested Queries এবং Batch Operations ব্যবহার করে জটিল কোয়েরি দ্রুত করা।
- Caching ব্যবহার করে পুনরাবৃত্তি কোয়েরির কার্যক্ষমতা বাড়ানো।
- Aggregation and Grouping প্রক্রিয়া ম্যানুয়ালি করা, যেখানে প্রয়োজন।
এই কৌশলগুলো ব্যবহার করে আপনি TinyDB তে জটিল কোয়েরি দ্রুত এবং কার্যকরভাবে চালাতে পারবেন।
Read more