আমার T
2 টি ক্ষেত্র সহ একটি সংগ্রহ রয়েছে: Grade1
এবং Grade2
, এবং আমি শর্তযুক্ত তাদের নির্বাচন Grade1 > Grade2
করতে চাই, আমি কীভাবে মাইএসকিউএল এর মতো একটি কোয়েরি পেতে পারি?
Select * from T Where Grade1 > Grade2
আমার T
2 টি ক্ষেত্র সহ একটি সংগ্রহ রয়েছে: Grade1
এবং Grade2
, এবং আমি শর্তযুক্ত তাদের নির্বাচন Grade1 > Grade2
করতে চাই, আমি কীভাবে মাইএসকিউএল এর মতো একটি কোয়েরি পেতে পারি?
Select * from T Where Grade1 > Grade2
উত্তর:
আপনি একটি $ যেখানে ব্যবহার করতে পারেন। কেবল সচেতন থাকুন এটি মোটামুটি ধীর হবে (প্রতিটি রেকর্ডে জাভাস্ক্রিপ্ট কোড চালাতে হবে) সুতরাং যদি আপনি পারেন তবে সূচকযুক্ত প্রশ্নের সাথে একত্রিত হন।
db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );
বা আরও কমপ্যাক্ট:
db.T.find( { $where : "this.Grade1 > this.Grade2" } );
সাম্প্রতিক উত্তরে$expr
বর্ণিত হিসাবে আপনি ব্যবহার করতে পারেন
$where: function() { return this.Grade1 - this.Grade2 > variable }
?
db.T.find({$where: function() {return this.startDate == ISODate("2017-01-20T10:55:08.000Z");}});
করেছি তখন এটি কিছুই দেয় না, এমনকি সংগ্রহের একটি ডকও ISODate("2017-01-20T10:55:08.000Z")
। কিন্তু <=
এবং >=
কাজ মনে হচ্ছে। কোন ধারণা?
this.startDate.getTime() == ISODate("2017-01-20T10:55:08.000Z").getTime()
আপনি নিয়মিত ক্যোয়ারিতে একত্রিতকরণ ফাংশনগুলি ব্যবহার করতে $ এক্সপ্রেস (3.6 মঙ্গো সংস্করণ অপারেটর) ব্যবহার করতে পারেন।
তুলনা query operators
বনাম aggregation comparison operators
।
নিয়মিত প্রশ্ন:
db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})
সমষ্টি প্রশ্ন:
db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})
যদি আপনার ক্যোয়ারীতে কেবলমাত্র $where
অপারেটর থাকে তবে আপনি কেবল জাভাস্ক্রিপ্ট এক্সপ্রেশনটিতে যেতে পারেন:
db.T.find("this.Grade1 > this.Grade2");
বৃহত্তর পারফরম্যান্সের জন্য, একটি সামগ্রিক অপারেশন চালান $redact
যা নথিকে ফিল্টার করার জন্য পাইপলাইন রয়েছে যা প্রদত্ত শর্তটি পূরণ করে fy
$redact
পাইপলাইন কার্যকারিতা অন্তর্ভুক্ত $project
এবং $match
মাঠ পর্যায় সম্পাদন যেখানে এটি শর্ত মিলে ব্যবহার করে সব কাগজপত্র ফিরে আসবে বাস্তবায়ন $$KEEP
ঐ যে ব্যবহার মিলছে না এবং পাইপলাইন ফলাফল থেকে সরিয়ে $$PRUNE
পরিবর্তনশীল।
$where
জাভাস্ক্রিপ্ট মূল্যায়নের পরিবর্তে জাভা স্ক্রিপ্ট মূল্যায়নের পরিবর্তে এটি একটি একক পাইপলাইন এবং নেটিভ মংগোডিবি অপারেটর ব্যবহার করে বৃহত সংগ্রহের জন্য ডকুমেন্টগুলি আরও দক্ষতার সাথে ফিল্টার করে নিম্নলিখিত সামগ্রিক অপারেশন চালানো $where
:
db.T.aggregate([
{
"$redact": {
"$cond": [
{ "$gt": [ "$Grade1", "$Grade2" ] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
যা দুটি পাইপলাইন অন্তর্ভুক্ত করার আরও সরলিকৃত সংস্করণ $project
এবং $match
:
db.T.aggregate([
{
"$project": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] },
"Grade1": 1,
"Grade2": 1,
"OtherFields": 1,
...
}
},
{ "$match": { "isGrade1Greater": 1 } }
])
সঙ্গে MongoDB 3.4 এবং নতুন:
db.T.aggregate([
{
"$addFields": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] }
}
},
{ "$match": { "isGrade1Greater": 1 } }
])
যদি পাঠযোগ্যতার চেয়ে কর্মক্ষমতা আরও গুরুত্বপূর্ণ হয় এবং যতক্ষণ না আপনার শর্তটি সাধারণ গাণিতিক ক্রিয়াকলাপ নিয়ে গঠিত, আপনি একত্রিত পাইপলাইন ব্যবহার করতে পারেন। প্রথমে, শর্তের বাম হাতের গণনা করতে $ প্রকল্পটি ব্যবহার করুন (সমস্ত ক্ষেত্রকে বাম হাতের দিকে নিয়ে যান)। তারপরে ধ্রুবক এবং ফিল্টারটির সাথে তুলনা করতে $ ম্যাচটি ব্যবহার করুন। এইভাবে আপনি জাভাস্ক্রিপ্ট সম্পাদন এড়াতে পারেন। নীচে পাইথনে আমার পরীক্ষা দেওয়া হল:
import pymongo
from random import randrange
docs = [{'Grade1': randrange(10), 'Grade2': randrange(10)} for __ in range(100000)]
coll = pymongo.MongoClient().test_db.grades
coll.insert_many(docs)
সামগ্রিক ব্যবহার:
%timeit -n1 -r1 list(coll.aggregate([
{
'$project': {
'diff': {'$subtract': ['$Grade1', '$Grade2']},
'Grade1': 1,
'Grade2': 1
}
},
{
'$match': {'diff': {'$gt': 0}}
}
]))
1 লুপ, প্রতি লুপ 1: 192 এমএসের মধ্যে সেরা
সন্ধান এবং কোথায় ব্যবহার করে:
%timeit -n1 -r1 list(coll.find({'$where': 'this.Grade1 > this.Grade2'}))
1 লুপ, প্রতি লুপ 1: 4.54 এর মধ্যে সেরা