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

किसी सरणी के कम से कम N तत्वों का मिलान शर्तों की सूची से करें

आपके प्रश्न की मेरे लिए दो संभावनाएं हैं, लेकिन शायद आपको आरंभ करने के लिए कुछ स्पष्टीकरण दें।

सबसे पहले मुझे आपको यह समझाने की आवश्यकता है कि आप <के इरादे को गलत समझते हैं। मजबूत>$elemMatch और इस मामले में इसका दुरुपयोग किया जाता है।

$elemMatch का विचार एक "क्वेरी दस्तावेज़" बनाना है जो वास्तव में सरणी के तत्वों पर लागू होता है। आशय यह है कि आपके पास सरणी के भीतर किसी दस्तावेज़ पर "एकाधिक शर्तें" हैं ताकि इसे सदस्य दस्तावेज़ के भीतर अलग-अलग मिलान किया जा सके, न कि बाहरी दस्तावेज़ की पूरी सरणी के भीतर। यानी:

{
   "data": [
       { "a": 1, "b": 3 },
       { "a": 2, "b": 2 }
   ]
}

और निम्न क्वेरी काम करेगी, भले ही उस सरणी में कोई वास्तविक एकल तत्व मेल नहीं खाता, लेकिन पूरा दस्तावेज़ करता है:

db.collection.find({ "data.a": 1, "data.b": 2 })

लेकिन यह जांचने के लिए कि क्या कोई वास्तविक तत्व उन दोनों स्थितियों से मेल खाता है, यह वह जगह है जहां आप $elemMatch का उपयोग करते हैं :

db.collection.find({ "data": { "a": 1, "b": 2 } })

तो उस नमूने में कोई मेल नहीं है, और यह केवल वहीं मेल खाएगा जहां एक विशिष्ट सरणी तत्व में वे दोनों तत्व थे।

अब हमारे पास $elemMatch . है समझाया गया है, यह रही आपकी सरलीकृत क्वेरी:

db.collection.find({ "tracks.artist": { "$in": arr } })

बहुत अधिक सरल है, और यह सभी सरणी सदस्यों को एक फ़ील्ड द्वारा देखकर काम करता है और जहां दस्तावेज़ में किसी भी तत्व में कम से कम उन संभावित परिणामों में से एक होता है।

लेकिन वह नहीं जो आप पूछ रहे हैं, इसी तरह आपके प्रश्न के साथ। यदि आप उस अंतिम कथन को पढ़ते हैं तो आपको पता चल जाएगा कि $में वास्तव में एक $or है स्थि‍ति। दस्तावेज़ में एक ही तत्व के बारे में "या" पूछने के लिए यह सिर्फ एक छोटा रूप है।

इसे ध्यान में रखते हुए, आप जो पूछ रहे हैं उसके मूल में एक "और" . है ऑपरेशन जहां सभी "तीन" मान निहित हैं। यह मानते हुए कि आप परीक्षण में केवल "तीन" आइटम भेज रहे थे, तो आप $और जो $all<के संक्षिप्त रूप में है /कोड> :

db.collection.find({ "tracks.artist": { "$all": arr } })

यह आपको केवल उन दस्तावेज़ों को लौटाएगा जिनमें परीक्षण स्थिति में निर्दिष्ट तत्वों के "सभी" से मेल खाने वाले उस सरणी के सदस्यों के भीतर तत्व था। यह वही हो सकता है जो आप चाहते हैं, लेकिन ऐसा मामला है जहां निश्चित रूप से आप परीक्षण के लिए "चार या अधिक" कलाकारों की एक सूची निर्दिष्ट करना चाहते हैं और केवल "तीन" या उसमें से कुछ कम संख्या चाहते हैं, इस मामले में एक $all ऑपरेटर बहुत संक्षिप्त है।

लेकिन इसे हल करने का एक तार्किक तरीका है, यह बस थोड़ा और प्रसंस्करण लेता है, ऑपरेटरों के साथ बुनियादी प्रश्नों के लिए उपलब्ध नहीं है, लेकिन यह एकत्रीकरण ढांचा :

var arr = ["A","B","C","D"];     // List for testing

db.collection.aggregate([
    // Match conditions for documents to narrow down
    { "$match": {
        "tracks.artist": { "$in": arr },
        "tracks.2": { "$exists": true }      // you would construct in code
    }},

    // Test the array conditions
    { "$project": {
        "user": 1,
        "tracks": 1,                         // any fields you want to keep
        "matched": {
            "$gte": [
                 { "$size": {
                     "$setIntersection": [
                         { "$map": {
                             "input": "$tracks",
                             "as": "t",
                             "in": { "$$t.artist" }
                         }},
                         arr
                     ]
                 }},
                 3
             ]
        }
    }},

    // Filter out anything that did not match
    { "$match": { "matched": true } }
])

पहला चरण एक मानक क्वेरी को लागू करता है $match शर्तों को पूरा करने के लिए दस्तावेज़ों को केवल उन लोगों तक फ़िल्टर करने के लिए जो शर्तों से मेल खाने के लिए "संभावित" हैं। यहां तार्किक मामला $in<का उपयोग करना है /कोड> पहले की तरह यह उन दस्तावेज़ों को खोजेगा जहाँ आपके "परीक्षण" सरणी में मौजूद तत्वों में से कम से कम एक दस्तावेज़ स्वयं के सरणी में सदस्य फ़ील्ड में से कम से कम एक के भीतर मौजूद है।

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

चूंकि सभी MongoDB प्रश्न अनिवार्य रूप से केवल डेटा संरचना का प्रतिनिधित्व करते हैं, यह इसे बनाना बहुत आसान बनाता है। यानी, जावास्क्रिप्ट के लिए:

var matchCount = 3;    // how many matches we want

var match1 = { "$match": { "tracks.artist": { "$in": arr } } };

match1["$match"]["tracks."+ (matchCount-1)] = { "$exits": true };

तर्क यह है कि "डॉट नोटेशन" फॉर्म के साथ $मौजूद है निर्दिष्ट सूचकांक ( n-1 ) पर एक तत्व की उपस्थिति के लिए परीक्षण, और कम से कम उस लंबाई की सरणी के लिए इसे वहां होना चाहिए।

बाकी का संकुचन आदर्श रूप से $ का उपयोग करता है सेटइंटरसेक्शन वास्तविक सरणी और परीक्षण किए गए सरणी के बीच मिलान किए गए तत्वों को वापस करने के लिए विधि। चूंकि दस्तावेज़ में सरणी "परीक्षण सरणी" के लिए संरचना से मेल नहीं खाती है, इसलिए इसे $नक्शा ऑपरेशन जो प्रत्येक सरणी तत्व से केवल "कलाकार" फ़ील्ड को वापस करने के लिए सेट है।

जैसा कि उन दो सरणियों का "चौराहा" बनाया गया है, अंत में इसका परीक्षण $आकार सामान्य तत्वों की उस परिणामी सूची में जहां यह देखने के लिए परीक्षण लागू किया जाता है कि उन तत्वों में से "कम से कम तीन" समान पाए गए।

अंत में आप $मिलान हालत।

आदर्श रूप से आप उन ऑपरेटरों को उपलब्ध कराने के लिए MongoDB 2.6 या इससे अधिक का उपयोग कर रहे हैं। 2.2.x और 2.4.x के पुराने संस्करणों के लिए, यह अभी भी संभव है, लेकिन बस थोड़ा और काम और ओवरहेड प्रोसेसिंग:

db.collection.aggregate([
    // Match conditions for documents to narrow down
    { "$match": {
        "tracks.artist": { "$in": arr },
        "tracks.2": { "$exists": true }      // you would construct in code
    }},

    // Unwind the document array
    { "$unwind": "$tracks" },

    // Filter the content
    { "$match": { "tracks.artist": { "$in": arr } }},

    // Group for distinct values
    { "$group": {
        "_id": { 
           "_id": "$_id",
           "artist": "$tracks.artist"
        }
    }},

    // Make arrays with length
    { "$group": {
        "_id": "$_id._id",
        "artist": { "$push": "$_id.artist" },
        "length": { "$sum": 1 }
    }},

    // Filter out the sizes
    { "$match": { "length": { "$gte": 3 } }}
])



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. मोंगोडब दस्तावेज़ को लॉक करना संभव नहीं है। अगर मुझे चाहिए तो क्या होगा?

  2. जावास्क्रिप्ट का उपयोग करके Azure फ़ंक्शंस के साथ डेटाबेस कनेक्शन का पुन:उपयोग करना

  3. JSON क्रमांकन Mongodb

  4. MongoTemplate मानदंड क्वेरी

  5. सी # ड्राइवर के माध्यम से मोंगोडब खोल स्क्रिप्ट निष्पादित करें

© कॉपीराइट http://hi.sqldat.com सर्वाधिकार सुरक्षित