আমার T2 টি ক্ষেত্র সহ একটি সংগ্রহ রয়েছে: Grade1এবং Grade2, এবং আমি শর্তযুক্ত তাদের নির্বাচন Grade1 > Grade2করতে চাই, আমি কীভাবে মাইএসকিউএল এর মতো একটি কোয়েরি পেতে পারি?
Select * from T Where Grade1 > Grade2
আমার T2 টি ক্ষেত্র সহ একটি সংগ্রহ রয়েছে: 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 এর মধ্যে সেরা