mongodb - মঙ্গোডিবিতে স্ট্রিংয়ের ক্ষেত্রের মান দৈর্ঘ্য




field string-length (4)

ক্ষেত্রের ডেটা ধরণ স্ট্রিং। আমি ডেটা আনতে চাই যেখানে ক্ষেত্রের নামের অক্ষরের দৈর্ঘ্য 40 এর চেয়ে বেশি।

আমি এই প্রশ্নের চেষ্টা করেছি কিন্তু ফিরে আসার ত্রুটি। 1।

db.usercollection.find(
{$where: "(this.name.length > 40)"}
).limit(2);

output :error: {
    "$err" : "TypeError: Cannot read property 'length' of undefined near '40)' ",
    "code" : 16722
}

এটি 2.4.9 এ কাজ করছে তবে আমার সংস্করণটি 2.6.5


অনেকগুলি নথি থাকলে $where এবং $expr সাথে অনুসন্ধানগুলি ধীর হয়।

$where , $expr চেয়ে $regex ব্যবহার খুব দ্রুত।

db.usercollection.find({ 
  "name": /^[\s\S]{40,}$/, // name.length >= 40
})

or 

db.usercollection.find({ 
  "name": { "$regex": "^[\s\S]{40,}$" }, // name.length >= 40
})

এই প্রশ্নের সাথে একই অর্থ

db.usercollection.find({ 
  "$where": "this.name && this.name.length >= 40",
})

or

db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gte": [ { "$strLenCP": "$name" }, 40 ] } 
})

আমি আমার সংগ্রহের জন্য প্রতিটি প্রশ্নের পরীক্ষা করেছি।

# find
$where: 10529.359ms
$expr: 5305.801ms
$regex: 2516.124ms

# count
$where: 10872.006ms
$expr: 2630.155ms
$regex: 158.066ms

আপনি এটি অর্জন করতে পারেন এমন একটি উপায় এখানে মঙ্গডব।

db.usercollection.find({ $where: 'this.name.length < 4' })

এই ক্যোয়ারী ক্ষেত্রের মান এবং দৈর্ঘ্য উভয়ই দেবে:

 db.usercollection.aggregate([ { $project: { "name": 1, "length": { $strLenCP: "$name" } }} ]) 

মঙ্গোডিবি 3.6 এবং আরও নতুনদের জন্য:

$expr অপারেটর কোয়েরি ভাষার মধ্যে $expr এক্সপ্রেশনগুলি ব্যবহারের অনুমতি দেয়, সুতরাং আপনি স্ট্রিংয়ের দৈর্ঘ্য পরীক্ষা করতে $strLenCP অপারেটরের $strLenCP উত্তোলন করতে পারেন:

db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } 
})

মঙ্গোডিবি 3.4 এবং আরও নতুনদের জন্য:

আপনি $redact পাইপলাইন অপারেটরের সাথে একত্রিতকরণ কাঠামোটিও ব্যবহার করতে পারেন যা আপনাকে d $cond অপারেটরের সাথে যৌক্তিক অবস্থার $$PRUNE এবং লজিকাল অবস্থাটি সত্য বা ডকুমেন্টটি "রাখার জন্য" বিশেষ ক্রিয়াকলাপ $$PRUNE শর্তটি মিথ্যা যেখানে দস্তাবেজটি "অপসারণ" করতে।

এই ক্রিয়াকলাপটি $project পাইপলাইন যা সংগ্রহের ক্ষেত্রগুলি নির্বাচন করে এবং একটি নতুন ক্ষেত্র তৈরি করে যা যৌক্তিক শর্ত জিজ্ঞাসা এবং তারপরে একটি পরবর্তী $match , $redact একক পাইপলাইন স্টেজ ব্যবহার করে যা আরও বেশি দক্ষ.

যৌক্তিক অবস্থা হিসাবে, স্ট্রিং $strLenCP অপারেটরগুলি রয়েছে যে আপনি স্ট্রিংয়ের দৈর্ঘ্য পরীক্ষা করতে $strLenCP অপারেটরটি ব্যবহার করতে পারেন। দৈর্ঘ্য যদি একটি নির্দিষ্ট মান $gt হয় তবে এটি একটি সত্যিকারের মিল এবং নথিটি "রাখা" হবে। অন্যথায় এটি "ছাঁটাই" এবং বাতিল করা হয়।

নিম্নলিখিত সামগ্রিক ক্রিয়াকলাপ চালানো বিবেচনা করুন যা উপরোক্ত ধারণাটি দেখায়:

db.usercollection.aggregate([
    { "$match": { "name": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$gt": [ { "$strLenCP": "$name" }, 40] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    { "$limit": 2 }
])

যদি $where ব্যবহার করছেন, ঘের বন্ধনীগুলি ছাড়া আপনার ক্যোয়ারীটি চেষ্টা করুন:

db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

ক্ষেত্রটির অস্তিত্ব পরীক্ষা করে তারপরে দৈর্ঘ্যটি পরীক্ষা করা আরও ভাল কোয়েরি হবে:

db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2); 

বা:

db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 
40"}).limit(2); 

মঙ্গোডিবি অ-evalu $where ক্যোয়ারী অপারেশনগুলির আগে মূল্যায়ন করে and $where অভিব্যক্তি এবং অ- $where ক্যোয়ারী স্টেটমেন্টগুলি কোনও সূচক ব্যবহার করতে পারে। আরও ভাল পারফরম্যান্স হ'ল স্ট্রিংয়ের দৈর্ঘ্যকে অন্য ক্ষেত্র হিসাবে সংরক্ষণ করা এবং তারপরে আপনি এটি সূচী বা অনুসন্ধান করতে পারেন; আবেদন $where তার তুলনায় অনেক ধীর হবে। এটি জাভাস্ক্রিপ্ট এক্সপ্রেশন এবং $where আপনি অন্য কোনও উপায়ে ডেটা স্ট্রাকচার করতে পারবেন না, বা আপনি যখন ডেটার একটি ছোট উপসেট নিয়ে কাজ করছেন তখন সর্বশেষ অবলম্বন হিসাবে অপারেটর ব্যবহার করার পরামর্শ দেওয়া হয়।

একটি পৃথক এবং দ্রুত পদ্ধতির যা operator $where অপারেটর $regex অপারেটর $regex এর ব্যবহার এড়ানো যায়। নিম্নলিখিত প্যাটার্নটি যা অনুসন্ধান করে তা বিবেচনা করুন

db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2); 

দ্রষ্টব্য - docs থেকে:

যদি ক্ষেত্রটির জন্য কোনও সূচক বিদ্যমান থাকে, তবে মংগাডিবি সূচকগুলিতে মানগুলির সাথে নিয়মিত অভিব্যক্তির সাথে মেলে যা সংগ্রহ স্ক্যানের চেয়ে দ্রুততর হতে পারে। নিয়মিত প্রকাশটি যদি একটি "উপসর্গ এক্সপ্রেশন" হয় তবে আরও অনুকূলিতকরণ ঘটতে পারে যার অর্থ সমস্ত সম্ভাব্য মিলগুলি একই স্ট্রিং দিয়ে শুরু হয়। এটি মঙ্গোডিবিকে সেই উপসর্গ থেকে একটি "ব্যাপ্তি" তৈরি করতে এবং কেবলমাত্র সেই পরিসরের মধ্যে থাকা সূচি থেকে পাওয়া মানগুলির সাথে মেলে।

একটি নিয়মিত প্রকাশটি হ'ল একটি "উপসর্গের অভিব্যক্তি" যদি এটি ক্যারেট (^) বা বাম অ্যাঙ্কর (\A) , তার পরে সরল চিহ্নগুলির একটি স্ট্রিং থাকে। উদাহরণস্বরূপ, রেজেক্স /^abc.*/ কেবলমাত্র সূচক থেকে শুরু হওয়া মানগুলির সাথে মেলে ধরে অনুকূলিত হবে যা abc দিয়ে শুরু হয়।

অতিরিক্ত হিসাবে, যখন /^a/, /^a.*/, এবং /^a.*$/ সমতুল্য স্ট্রিং মেলে, তাদের পারফরম্যান্সের বৈশিষ্ট্যগুলি পৃথক রয়েছে। এই সমস্ত এক্সপ্রেশন একটি সূচক ব্যবহার করে যদি একটি উপযুক্ত সূচক উপস্থিত থাকে; তবে, /^a.*/ , এবং /^a.*$/ আরও ধীর। /^a/ উপসর্গের সাথে মিলে স্ক্যান করা বন্ধ করতে পারে।





string-length