2 ক্ষেত্রের সাথে তুলনা করার জন্য মঙ্গোবিবি ক্যোয়ারী শর্ত


108

আমার T2 টি ক্ষেত্র সহ একটি সংগ্রহ রয়েছে: Grade1এবং Grade2, এবং আমি শর্তযুক্ত তাদের নির্বাচন Grade1 > Grade2করতে চাই, আমি কীভাবে মাইএসকিউএল এর মতো একটি কোয়েরি পেতে পারি?

Select * from T Where Grade1 > Grade2

উত্তর:


120

আপনি একটি $ যেখানে ব্যবহার করতে পারেন। কেবল সচেতন থাকুন এটি মোটামুটি ধীর হবে (প্রতিটি রেকর্ডে জাভাস্ক্রিপ্ট কোড চালাতে হবে) সুতরাং যদি আপনি পারেন তবে সূচকযুক্ত প্রশ্নের সাথে একত্রিত হন।

db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );

বা আরও কমপ্যাক্ট:

db.T.find( { $where : "this.Grade1 > this.Grade2" } );

মঙ্গোদব v.3.6 + এর জন্য ইউপিডি

সাম্প্রতিক উত্তরে$expr বর্ণিত হিসাবে আপনি ব্যবহার করতে পারেন


ওফস, আমি এটি পেয়েছি, কেবল যৌথ-ব্যবহারের জাভাস্ক্রিপ্ট বা অন্যান্য শেল স্ক্রিপ্টগুলি, উভয়কে ধন্যবাদ!
দিয়েগো চেং

16
আপনি এটি আরও কিছুটা কমপ্যাক্ট করতে পারেন ...> db.T.find ({$ যেখানে: "this.Grad1> this.Grad2"});
জাস্টিন জেনকিনস

আমি কিভাবে করতে পারি $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")। কিন্তু <=এবং >=কাজ মনে হচ্ছে। কোন ধারণা?
ক্যাটিজ

@ কেটায়স সম্ভবত কিছুটা দেরি করেছে ... তবে খাঁটি জাভাস্ক্রিপ্ট একটি == করার সময় 2 তারিখের মধ্যে তুলনা করে সর্বদা মিথ্যা বলে। মঙ্গো তবে আপনাকে ক্যোয়ারিতে তারিখের মধ্যে সঠিক মিলগুলির জন্য অনুসন্ধান করতে দেয়। এক কার্যসংক্রান্ত মিলিসেকেন্ড বা যাই হোক না কেন রূপান্তর .getTime () ব্যবহার করছেthis.startDate.getTime() == ISODate("2017-01-20T10:55:08.000Z").getTime()
leinaD_natipaC

53

আপনি নিয়মিত ক্যোয়ারিতে একত্রিতকরণ ফাংশনগুলি ব্যবহার করতে $ এক্সপ্রেস (3.6 মঙ্গো সংস্করণ অপারেটর) ব্যবহার করতে পারেন।

তুলনা query operatorsবনাম aggregation comparison operators

নিয়মিত প্রশ্ন:

db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})

সমষ্টি প্রশ্ন:

db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})

39

যদি আপনার ক্যোয়ারীতে কেবলমাত্র $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 } }
])

শেষটি আমার সাথে কাজ করছে বলে মনে হয় না। ইজগ্র্যাড 1 গ্রেটার ফিল্ডটি সঠিকভাবে যুক্ত এবং মূল্যায়ন করা হয় তবে কিছু কারণে কোয়েরিটি সমস্ত সারিগুলির সাথে মেলে তবে গ্রেড 1 গ্রেটারের মান বিবেচনা করা উচিত। এই আচরণের কারণ কী হতে পারে? সম্পাদনা: কিছু মনে করবেন না, আমি একত্রিত করার জন্য একটি অ্যারে পাস করতে চাইছিলাম না () বরং প্রতিটি পরামিতি নিজেই প্যারামিটার হিসাবে, এটি মিস করে missed
ThatBrianDude

13

যদি পাঠযোগ্যতার চেয়ে কর্মক্ষমতা আরও গুরুত্বপূর্ণ হয় এবং যতক্ষণ না আপনার শর্তটি সাধারণ গাণিতিক ক্রিয়াকলাপ নিয়ে গঠিত, আপনি একত্রিত পাইপলাইন ব্যবহার করতে পারেন। প্রথমে, শর্তের বাম হাতের গণনা করতে $ প্রকল্পটি ব্যবহার করুন (সমস্ত ক্ষেত্রকে বাম হাতের দিকে নিয়ে যান)। তারপরে ধ্রুবক এবং ফিল্টারটির সাথে তুলনা করতে $ ম্যাচটি ব্যবহার করুন। এইভাবে আপনি জাভাস্ক্রিপ্ট সম্পাদন এড়াতে পারেন। নীচে পাইথনে আমার পরীক্ষা দেওয়া হল:

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 এর মধ্যে সেরা

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.