MongoDB-এ একই ডকুমেন্টের একাধিক ফিল্ড বা অ্যারে এলিমেন্ট পারস্পরিক তুলনা করতে $where অপারেটর ব্যবহার করা হয়। এটি জাভাস্ক্রিপ্ট এক্সপ্রেশন চালাতে দেয়।
কলেকশন এবং ডকুমেন্ট তৈরি
> db.demo223.insertOne({"Scores":[56,78]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4ca03d395bdc2134730") }
> db.demo223.insertOne({"Scores":[88,45]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4d103d395bdc2134731") }
> db.demo223.insertOne({"Scores":[98,79]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee4d803d395bdc2134732") }
সব ডকুমেন্ট দেখানো
> db.demo223.find();
আউটপুট:
{ "_id" : ObjectId("5e3ee4ca03d395bdc2134730"), "Scores" : [ 56, 78 ] }
{ "_id" : ObjectId("5e3ee4d103d395bdc2134731"), "Scores" : [ 88, 45 ] }
{ "_id" : ObjectId("5e3ee4d803d395bdc2134732"), "Scores" : [ 98, 79 ] }
একাধিক প্রপার্টি তুলনা করার কোয়ারী
$where ক্লজে জাভাস্ক্রিপ্ট এক্সপ্রেশন this.Scores[0] > this.Scores[1] ব্যবহার করা হয়েছে:
> db.demo223.find({ $where : "this.Scores[0] > this.Scores[1]" });
ফলাফল
{ "_id" : ObjectId("5e3ee4d103d395bdc2134731"), "Scores" : [ 88, 45 ] }
{ "_id" : ObjectId("5e3ee4d803d395bdc2134732"), "Scores" : [ 98, 79 ] }
ব্যাখ্যা:
- প্রথম ডকুমেন্ট: 56 > 78? False → বাদ
- দ্বিতীয় ডকুমেন্ট: 88 > 45? True → রাখা
- তৃতীয় ডকুমেন্ট: 98 > 79? True → রাখা
⚠️ $where-এর সীমাবদ্ধতা এবং ঝুঁকি:
- পারফরম্যান্স: ইনডেক্স ব্যবহার করে না, ফুল কালেকশন স্ক্যান করে (খুব ধীর বড় ডেটাসেটে)
- সিকিউরিটি: জাভাস্ক্রিপ্ট এক্সিকিউশন - ইনজেকশন ঝুঁকি (user input সরাসরি নাও দিন)
- লকিং: গ্লোবাল লক ধরে (পুরানো ভার্সনে)
- ডিপ্রিকেটেড: ভবিষ্যতে সরানো হয়ে যেতে পারে
বিকল্প পদ্ধতি (প্রস্তাবিত - Aggregate with $expr):
db.demo223.aggregate([
{ $match: { $expr: { $gt: [ { $arrayElemAt: ["$Scores", 0] }, { $arrayElemAt: ["$Scores", 1] } ] } } }
])
$expr + $gt + $arrayElemAt - এটি ইনডেক্স ব্যবহার করতে পারে (partial index সহ), নেটিভ BSON কম্পারিজন করে, এবং সিকিউর।
অন্যান্য তুলনা উদাহরণ:
- দুই ফিল্ড:
{$expr: {$gt: ["$field1", "$field2"]}} - অ্যারে লেন্থ:
{$expr: {$gt: [{$size: "$arr1"}, {$size: "$arr2"}]}}