2012-03-27 13 views
9

मैं उन सभी उपयोगकर्ताओं को खोजने के लिए मोंगो डीबी में एक कुशल क्वेरी बनाना चाहता हूं, जिनके उपयोगकर्ता उपयोगकर्ता समूह में सूचीबद्ध उपयोगकर्ता हैं। आदर्श रूप में मैं इसे मोंगोद को एक ही अनुरोध के रूप में बनाना चाहता हूं। जो मैं चाहता हूं वह SQL में नेस्टेड चयनों के अनुरूप है। मैं मोंगो खोल में इस की कोशिश की है:मोंगो डीबी में नेस्टेड प्रश्नों को कैसे बनाया जाए जो नेस्टेड एसक्यूएल चुनिंदा प्रश्नों की तरह काम करता है

db.user.save({_id:"u1", Name:"u1 name"}); 
db.user.save({_id:"u2", Name:"u1 name"}); 
db.user.save({_id:"u3", Name:"u3 name"}); 
db.usergroup.save({_id:"g1", Users: ["u2","u3"]}); 

अब यहाँ का चयन मैं क्या करना चाहते है, लेकिन हार्डकोड बिना [ "यू 2", "यू 3"] सरणी:

db.user.find({_id:{$in:["u2","u3"]}}).forEach(printjson); 

यह ठीक काम करता है और यू 2 और यू 3 के लिए उपयोगकर्ता ऑब्जेक्ट देता है।

अब प्रश्न यह है कि एक क्वेरी के साथ निकाले गए ऑपरेटर में $ में उपयोगकर्ता आईडी की सरणी कैसे प्राप्त करें, ताकि संपूर्ण क्वेरी एक अनुरोध के साथ की जा सके।

इस तरह एक "नेस्टेड क्वेरी" काम नहीं करता: मंगल मार्च 27 06:17:41 न आया हुआ अपवाद: त्रुटि: { "$ अं":

db.user.find({_id:{$in:db.usergroup.find({_id:"g1"},{_id:0,Users:1})}}).forEach(printjson); 

इस त्रुटि देता है "अवैध क्वेरी" , "कोड": 12580} लोड करने में विफल: mongoNestedSelect.js

1) क्या यह मोंगोडब में और कैसे संभव है?

2) आधिकारिक सी # ड्राइवर के साथ ऐसा कैसे करें?

उत्तर

5

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

स्पष्ट रूप से यह केवल तभी काम करेगा यदि आपकी उपयोगकर्ता समूह सूची (नामों के साथ) एक दस्तावेज़ में फिट हो सकती है, लेकिन आपके वर्तमान दृष्टिकोण में समूह के अधिकतम आकार से संबंधित कुछ सीमाएं भी हैं।

एक और दृष्टिकोण उन समूहों को स्टोर करना होगा जो उपयोगकर्ता प्रत्येक 'उपयोगकर्ता' दस्तावेज़ पर किसी सरणी में संबंधित होते हैं। उस सरणी फ़ील्ड पर एक अनुक्रमणिका जोड़ें और अब आप समूह द्वारा उपयोगकर्ताओं को पा सकते हैं। यह देखते हुए कि एक समूह में सदस्यों के मुकाबले कम समूह से संबंधित होने की संभावना है, यह यहां सबसे अच्छा तरीका हो सकता है।

db.user.save({_id:"u1", name:"u1 name", groups:[{_id:"g1", name:"Group One"}, ...]}); 

फिर आप ताकि आप तुरंत समूहों की सूची एक उपयोगकर्ता एक ही राउंड ट्रिप के साथ के अंतर्गत आता है प्रदर्शित कर सकते हैं अपने _ id के साथ समूह का नाम संग्रहीत कर सकता है। बेशक, यदि आप किसी समूह के नाम को बदलने की अनुमति देते हैं तो आपको नाम की इन सभी प्रतियों को ठीक करने के लिए पृष्ठभूमि कार्य को बंद करना होगा।

मैं अपने आप के बजाय मोंगोडीबी आईडी जनरेटर में भी निर्मित का उपयोग करता हूं, इसमें कई वांछनीय गुण हैं।

+0

ठीक धन्यवाद। तो मोंगोडीबी में "असली घोंसला प्रश्न" संभव नहीं हैं? और हाँ मैं ऑब्जेक्ट आईडी के बारे में आपकी टिप्पणी से सहमत हूं, लेकिन मैंने सामानों को सरल रखने के लिए इस उदाहरण में तारों का उपयोग किया था। – ssn

+0

दाएं, कोई नेस्टेड प्रश्न नहीं, आपके डेटा को संरचित करने की आवश्यकता है ताकि आप डेटाबेस में अनुरोधों के एकल (या न्यूनतम संख्या) के साथ जो चाहते हैं उसे प्राप्त कर सकें। –

5

समारोह

function bbb(){ 
    var org_ids = new Array(); 
    var orgs = 
     db.orgTreeNode.find({ancestors:"ca5cd344-ba47-4601-a07b-ea2c684bfb4e"},{"_id":1}); 
    orgs.forEach(function(org){ 
     org_ids.push(org._id); 
    }) 

    return db.user.find({"org":{$in:org_ids}}).skip(300).limit(10); 
} 

निष्पादित समारोह

bbb() 
1

परिभाषित यह आप ans--

db.users.find({ 
    _id: { 
     $in: db.logs.find({ 
      loggedbyuser: { 
       $ne: ObjectId("569f9d093447ee781ca80b52") 
      }, 
      logtype: "marketfetched", 
      "logcreated": { 
       $gt: new ISODate("2016-02-06T00:00:00.871Z") 
      } 
     }, { 
      loggedbyuser: 1, 
      _id: 0 
     }).sort({ 
      'logcreated': -1 
     }).map(function(like) { 
      return like.loggedbyuser; 
     }) 
    } 
}).map(function(like) { 
    return like.fullname; 
}); 
+1

ओप एसक्यूएल के समान घोंसला वाली क्वेरी मांग रहा है जो डीबी के अंदर केवल एक चरण में निष्पादित करता है। आप बस "नेस्टेड" क्वेरी के परिणाम ला रहे हैं, और इसे फिर से तार पर भेज रहे हैं। –

1

-sUReN

प्राप्त करने के लिए गति प्रदान कर सकते हैं

एसक्यूएल क्वेरी: (अलग से & गिनती द्वारा समूह)

select city,count(distinct(emailId)) from TransactionDetails group by city; 

समतुल्य मोंगो क्वेरी इस प्रकार दिखाई देगा:

db.TransactionDetails.aggregate([ 
{$group:{_id:{"CITY" : "$cityName"},uniqueCount: {$addToSet: "$emailId"}}}, 
{$project:{"CITY":1,uniqueCustomerCount:{$size:"$uniqueCount"}} } 
]); 
संबंधित मुद्दे