MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

$regex को $ के अंदर या एकत्रीकरण अभिव्यक्ति के रूप में कैसे उपयोग करें

अंदर सब कुछ $expr एक एकत्रीकरण अभिव्यक्ति है, और दस्तावेज़ीकरण "यह नहीं कह सकता कि आप स्पष्ट रूप से नहीं कह सकते" , लेकिन किसी भी नामित ऑपरेटर की कमी और JIRA समस्या SERVER-11947 निश्चित रूप से ऐसा कहो। इसलिए यदि आपको रेगुलर एक्सप्रेशन की आवश्यकता है तो आपके पास वास्तव में का उपयोग करने के अलावा कोई अन्य विकल्प नहीं है। $कहां इसके बजाय:

db.getCollection('permits').find({
  "$where": function() {
    var description = this.inspections
       .sort((a,b) => b.inspectionDate.valueOf() - a.inspectionDate.valueOf())
       .shift().description;

     return /^Found a .* at the property$/.test(description) ||
           description === "Health Inspection";

  }
})

आप अब भी $expr का इस्तेमाल कर सकते हैं और सटीक मिलान के लिए एग्रीगेशन एक्सप्रेशन, या तुलना को <के भीतर रखें कोड>$कहां वैसे भी। लेकिन इस समय MongoDB केवल वही रेगुलर एक्सप्रेशन समझता है जो $regex एक "query" एक्सप्रेशन के भीतर ।

यदि आपने वास्तव में "आवश्यकता" . किया था एक एकत्रीकरण पाइपलाइन अभिव्यक्ति जो आपको $where , तो केवल वर्तमान वैध दृष्टिकोण पहले क्षेत्र को सरणी से अलग "प्रोजेक्ट" करना है और फिर $मिलान रेगुलर क्वेरी एक्सप्रेशन के साथ:

db.getCollection('permits').aggregate([
  { "$addFields": {
     "lastDescription": {
       "$arrayElemAt": [
         "$inspections.description",
         { "$indexOfArray": [
           "$inspections.inspectionDate",
           { "$max": "$inspections.inspectionDate" }
         ]}
       ]
     }
  }},
  { "$match": {
    "lastDescription": {
      "$in": [/^Found a .* at the property$/,/Health Inspection/]
    }
  }}
])

जो हमें इस तथ्य की ओर ले जाता है कि आप अधिकतम दिनांक मान वाले सरणी में आइटम की तलाश कर रहे हैं। जावास्क्रिप्ट सिंटैक्स को यह स्पष्ट करना चाहिए कि यहां सही दृष्टिकोण के बजाय है। $क्रमबद्ध "अद्यतन" पर सरणी। इस तरह सरणी में "पहला" आइटम "नवीनतम" हो सकता है। और यह कुछ ऐसा है जो आप नियमित क्वेरी के साथ कर सकते हैं।

आदेश को बनाए रखने के लिए, सुनिश्चित करें कि नए आइटम सरणी में जोड़े गए हैं $पुश और $sort इस तरह:

db.getCollection('permits').updateOne(
  { "_id": _idOfDocument },
  {
    "$push": {
      "inspections": {
        "$each": [{ /* Detail of inspection object */ }],
        "$sort": { "inspectionDate": -1 }
      }
    }
  }
)

वास्तव में एक खाली सरणी तर्क के साथ $each एक updateMany() आपके सभी मौजूदा दस्तावेज़ों को अपडेट कर देगा:

db.getCollection('permits').updateMany(
  { },
  {
    "$push": {
      "inspections": {
        "$each": [],
        "$sort": { "inspectionDate": -1 }
      }
    }
  }
)

ये वास्तव में केवल तभी आवश्यक होने चाहिए जब आप वास्तव में अपडेट के दौरान संग्रहीत तिथि को "बदल" देते हैं, और उन अपडेट को बल्कराइट () अद्यतन और सरणी के "क्रमबद्ध" दोनों को प्रभावी ढंग से करने के लिए:

db.getCollection('permits').bulkWrite([
  { "updateOne": {
    "filter": { "_id": _idOfDocument, "inspections._id": indentifierForArrayElement },
    "update": {
      "$set": { "inspections.$.inspectionDate": new Date() }
    }
  }},
  { "updateOne": {
    "filter": { "_id": _idOfDocument },
    "update": {
      "$push": { "inspections": { "$each": [], "$sort": { "inspectionDate": -1 } } }
    }
  }}
])

हालांकि यदि आपने वास्तव में कभी भी तिथि को "बदल" नहीं दिया है, तो शायद $स्थिति "संलग्न" के बजाय सरणी में संशोधक और "प्री-पेंड" करें, और $सॉर्ट करें :

db.getCollection('permits').updateOne(
  { "_id": _idOfDocument },
  { 
    "$push": { 
      "inspections": {
        "$each": [{ /* Detail of inspection object */ }],
        "$position": 0
      }
    }
  }
)

सरणी के साथ स्थायी रूप से क्रमबद्ध या कम से कम निर्मित इसलिए "नवीनतम" तिथि वास्तव में हमेशा "पहली" प्रविष्टि होती है, तो आप बस एक नियमित क्वेरी अभिव्यक्ति का उपयोग कर सकते हैं:

db.getCollection('permits').find({
  "inspections.0.description": { 
    "$in": [/^Found a .* at the property$/,/Health Inspection/]
  }
})

तो यहां सबक यह है कि गणना की गई अभिव्यक्तियों को अपने तर्क पर लागू करने की कोशिश न करें जहां आपको वास्तव में आवश्यकता नहीं है। "नवीनतम दिनांक पहली रखने के लिए आप सरणी सामग्री को "संग्रहीत" के रूप में क्यों नहीं ऑर्डर कर सकते, इसका कोई अनिवार्य कारण नहीं होना चाहिए " , और यहां तक ​​​​कि अगर आपको लगता है कि आपको किसी अन्य क्रम में सरणी की आवश्यकता है, तो आपको शायद यह देखना चाहिए कि कौन सा उपयोग मामला अधिक महत्वपूर्ण है।

एक बार पुन:व्यवस्थित करने के बाद आप कुछ हद तक किसी इंडेक्स का लाभ उठा सकते हैं, जब तक कि रेगुलर एक्सप्रेशन या तो स्ट्रिंग की शुरुआत से जुड़े होते हैं या क्वेरी एक्सप्रेशन में कम से कम कुछ और सटीक मिलान करता है।

यदि आपको लगता है कि आप वास्तव में सरणी को पुन:व्यवस्थित नहीं कर सकते हैं, तो $कहां जब तक JIRA समस्या का समाधान नहीं हो जाता, तब तक केवल क्वेरी ही आपका वर्तमान विकल्प है। जो वास्तव में वर्तमान में लक्षित 4.1 रिलीज के लिए है, लेकिन यह सबसे अच्छे अनुमान पर 6 महीने से एक वर्ष तक की संभावना से अधिक है।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. स्प्रिंग-डेटा-मोंगोडब बहु-किरायेदार बनाना

  2. MongoDB:सरणी में एक सरणी अद्यतन कर रहा है

  3. MongoDB उच्चतम मिलान द्वारा उत्पाद खोज क्रम को प्रतिस्थापित करता है

  4. सास के लिए MongoDB में एकाधिक डेटाबेस

  5. MongoDB एकत्रीकरण ढांचे में शून्य से विभाजन को कैसे संभालें